Web Inspector: show whitespace characters in DTE
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Feb 2013 09:58:10 +0000 (09:58 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Feb 2013 09:58:10 +0000 (09:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=108947

Patch by Andrey Lushnikov <lushnikov@chromium.org> on 2013-02-09
Reviewed by Pavel Feldman.

Source/WebCore:

New test: inspector/editor/text-editor-show-whitespaces.html

Split consecutive whitespace characters into groups of 16, 8, 4, 2 and 1 and
add ::before pseudoclass for this groups which contains necessary
amount of "dots" (u+00b7). Add a setting "Show whitespace" for this
option in "Sources" section of "General" tab.

* English.lproj/localizedStrings.js:
* inspector/front-end/DefaultTextEditor.js:
(WebInspector.TextEditorMainPanel.prototype.wasShown):
(WebInspector.TextEditorMainPanel.prototype.willHide):
(WebInspector.TextEditorMainPanel.prototype._renderRanges):
(WebInspector.TextEditorMainPanel.prototype._renderWhitespaceCharsWithFixedSizeSpans):
(WebInspector.TextEditorMainPanel.prototype._paintLine):
* inspector/front-end/Settings.js:
* inspector/front-end/SettingsScreen.js:
(WebInspector.GenericSettingsTab):
* inspector/front-end/inspectorSyntaxHighlight.css:
(.webkit-whitespace-1::before):
(.webkit-whitespace-2::before):
(.webkit-whitespace-4::before):
(.webkit-whitespace-8::before):
(.webkit-whitespace-16::before):
(.webkit-whitespace::before):

LayoutTests:

Add layout test to verify whitespace highlight functionality.

* inspector/editor/text-editor-show-whitespace-expected.txt: Added.
* inspector/editor/text-editor-show-whitespace.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/inspector/editor/text-editor-show-whitespace-expected.txt [new file with mode: 0644]
LayoutTests/inspector/editor/text-editor-show-whitespace.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/English.lproj/localizedStrings.js
Source/WebCore/inspector/front-end/DefaultTextEditor.js
Source/WebCore/inspector/front-end/Settings.js
Source/WebCore/inspector/front-end/SettingsScreen.js
Source/WebCore/inspector/front-end/inspectorSyntaxHighlight.css

index 28cc8bce29b9b32608c2f0e41ddb498adb3ee617..96d73f5323e62e9a1bff7bff557455e2fa554ff4 100644 (file)
@@ -1,3 +1,15 @@
+2013-02-09  Andrey Lushnikov  <lushnikov@chromium.org>
+
+        Web Inspector: show whitespace characters in DTE
+        https://bugs.webkit.org/show_bug.cgi?id=108947
+
+        Reviewed by Pavel Feldman.
+
+        Add layout test to verify whitespace highlight functionality.
+
+        * inspector/editor/text-editor-show-whitespace-expected.txt: Added.
+        * inspector/editor/text-editor-show-whitespace.html: Added.
+
 2013-02-08  Eric Carlson  <eric.carlson@apple.com>
 
         [Mac] respect in-band caption color
diff --git a/LayoutTests/inspector/editor/text-editor-show-whitespace-expected.txt b/LayoutTests/inspector/editor/text-editor-show-whitespace-expected.txt
new file mode 100644 (file)
index 0000000..2384905
--- /dev/null
@@ -0,0 +1,25 @@
+This test checks how text editor splits whitespace sequences to highlight them if the appropriate setting is set up.
+
+Actual text:
+function foo(a, b) {
+    // spaces in comment
+    a = "string with spaces";
+    a = 2;               a = 3;
+}
+========== Editor HTML showWhitespaceInEditor OFF ==========
+
+<div class="inner-container" tabindex="0">
+<div class="webkit-line-content"><span class="webkit-javascript-keyword">function</span><span class="webkit-whitespace"> </span><span class="webkit-javascript-ident">foo</span>(<span class="webkit-javascript-ident">a</span>,<span class="webkit-whitespace"> </span><span class="webkit-javascript-ident">b</span>)<span class="webkit-whitespace"> </span>{</div>
+<div class="webkit-line-content"><span class="webkit-whitespace">    </span><span class="webkit-javascript-comment">// spaces in comment</span></div>
+<div class="webkit-line-content"><span class="webkit-whitespace">    </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-string">"string with spaces"</span>;</div>
+<div class="webkit-line-content"><span class="webkit-whitespace">    </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-number">2</span>;<span class="webkit-whitespace">               </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace"> </span>=<span class="webkit-whitespace"> </span><span class="webkit-javascript-number">3</span>;</div>
+<div class="webkit-line-content">}</div></div>
+========== Editor HTML after setting showWhitespaceInEditor ON ==========
+
+<div class="inner-container" tabindex="0">
+<div class="webkit-line-content"><span class="webkit-javascript-keyword">function</span><span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-ident">foo</span>(<span class="webkit-javascript-ident">a</span>,<span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-ident">b</span>)<span class="webkit-whitespace webkit-whitespace-1"> </span>{</div>
+<div class="webkit-line-content"><span class="webkit-whitespace webkit-whitespace-4">    </span><span class="webkit-javascript-comment">// spaces in comment</span></div>
+<div class="webkit-line-content"><span class="webkit-whitespace webkit-whitespace-4">    </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace webkit-whitespace-1"> </span>=<span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-string">"string with spaces"</span>;</div>
+<div class="webkit-line-content"><span class="webkit-whitespace webkit-whitespace-4">    </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace webkit-whitespace-1"> </span>=<span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-number">2</span>;<span class="webkit-whitespace webkit-whitespace-8">        </span><span class="webkit-whitespace webkit-whitespace-4">    </span><span class="webkit-whitespace webkit-whitespace-2">  </span><span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-ident">a</span><span class="webkit-whitespace webkit-whitespace-1"> </span>=<span class="webkit-whitespace webkit-whitespace-1"> </span><span class="webkit-javascript-number">3</span>;</div>
+<div class="webkit-line-content">}</div></div>
+
diff --git a/LayoutTests/inspector/editor/text-editor-show-whitespace.html b/LayoutTests/inspector/editor/text-editor-show-whitespace.html
new file mode 100644 (file)
index 0000000..a75deb6
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<head>
+<script src="../../http/tests/inspector/inspector-test.js"></script>
+<script src="editor-test.js"></script>
+<script>
+function test()
+{
+function foo(a, b) {
+    // spaces in comment
+    a = "string with spaces";
+    a = 2;               a = 3;
+}
+
+    WebInspector.settings.showWhitespaceInEditor.set(false);
+    var textEditor = InspectorTest.createTestEditor();
+    textEditor.overrideViewportForTest(0, undefined, 3);
+    textEditor.mimeType = "text/javascript";
+    textEditor.setText(foo.toString());
+    InspectorTest.addResult("Actual text:");
+    InspectorTest.addResult(textEditor.text());
+    InspectorTest.addResult("========== Editor HTML showWhitespaceInEditor OFF ==========");
+    InspectorTest.dumpEditorHTML(textEditor, true);
+    WebInspector.settings.showWhitespaceInEditor.set(true);
+    InspectorTest.addResult("========== Editor HTML after setting showWhitespaceInEditor ON ==========");
+    InspectorTest.dumpEditorHTML(textEditor, true);
+    InspectorTest.completeTest();
+}
+
+</script>
+</head>
+
+<body onload="runTest();">
+<p>
+This test checks how text editor splits whitespace sequences to highlight them if the appropriate
+setting is set up.
+</p>
+</body>
+</html>
index dcb364c3f63faae2947a873813c87f87920a6c74..b8f147dbc57672d3f2923099a049208506d21a57 100644 (file)
@@ -1,3 +1,35 @@
+2013-02-09  Andrey Lushnikov  <lushnikov@chromium.org>
+
+        Web Inspector: show whitespace characters in DTE
+        https://bugs.webkit.org/show_bug.cgi?id=108947
+
+        Reviewed by Pavel Feldman.
+
+        New test: inspector/editor/text-editor-show-whitespaces.html
+
+        Split consecutive whitespace characters into groups of 16, 8, 4, 2 and 1 and
+        add ::before pseudoclass for this groups which contains necessary
+        amount of "dots" (u+00b7). Add a setting "Show whitespace" for this
+        option in "Sources" section of "General" tab.
+
+        * English.lproj/localizedStrings.js:
+        * inspector/front-end/DefaultTextEditor.js:
+        (WebInspector.TextEditorMainPanel.prototype.wasShown):
+        (WebInspector.TextEditorMainPanel.prototype.willHide):
+        (WebInspector.TextEditorMainPanel.prototype._renderRanges):
+        (WebInspector.TextEditorMainPanel.prototype._renderWhitespaceCharsWithFixedSizeSpans):
+        (WebInspector.TextEditorMainPanel.prototype._paintLine):
+        * inspector/front-end/Settings.js:
+        * inspector/front-end/SettingsScreen.js:
+        (WebInspector.GenericSettingsTab):
+        * inspector/front-end/inspectorSyntaxHighlight.css:
+        (.webkit-whitespace-1::before):
+        (.webkit-whitespace-2::before):
+        (.webkit-whitespace-4::before):
+        (.webkit-whitespace-8::before):
+        (.webkit-whitespace-16::before):
+        (.webkit-whitespace::before):
+
 2013-02-08  Eric Carlson  <eric.carlson@apple.com>
 
         [Mac] respect in-band caption color
index 0228aa903c14458f73d7fcdb282b6e2bdc5cd63f..7635229db5f83003122a88e8802d4d8d559b4174 100644 (file)
@@ -390,6 +390,7 @@ localizedStrings["Show rulers"] = "Show rulers";
 localizedStrings["Show Shadow DOM"] = "Show Shadow DOM";
 localizedStrings["Show times as percentages."] = "Show times as percentages.";
 localizedStrings["Show total and self times as percentages."] = "Show total and self times as percentages.";
+localizedStrings["Show whitespace"] = "Show whitespace";
 localizedStrings["Size"] = "Size";
 localizedStrings["Snapshot %d"] = "Snapshot %d";
 localizedStrings["End Time"] = "End Time";
index 2ae81de2e402f478d697d79e06286a8d556a3dc5..70dff34e0527820b4d70138d4c22367d5e887450 100644 (file)
@@ -1364,6 +1364,9 @@ WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScroll
     this.element.addEventListener("textInput", this._handleTextInput.bind(this), false);
     this.element.addEventListener("cut", this._handleCut.bind(this), false);
 
+    this._showWhitespace = WebInspector.settings.showWhitespaceInEditor.get();
+    this._handleShowWhitespaceInEditorChange = this._handleShowWhitespaceInEditorChange.bind(this);
+
     this._container.addEventListener("focus", this._handleFocused.bind(this), false);
 
     this._highlightDescriptors = [];
@@ -1377,6 +1380,14 @@ WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScroll
     this._registerShortcuts();
 }
 
+WebInspector.TextEditorMainPanel._ConsecutiveWhitespaceChars = {
+    1: " ",
+    2: "  ",
+    4: "    ",
+    8: "        ",
+    16: "                "
+};
+
 WebInspector.TextEditorMainPanel.prototype = {
     _registerShortcuts: function()
     {
@@ -1399,6 +1410,21 @@ WebInspector.TextEditorMainPanel.prototype = {
         this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
     },
 
+    _handleShowWhitespaceInEditorChange: function()
+    {
+        this._showWhitespace = WebInspector.settings.showWhitespaceInEditor.get();
+        var visibleFrom = this.scrollTop();
+        var visibleTo = visibleFrom + this.clientHeight();
+
+        if (!visibleTo)
+            return;
+
+        var result = this.findVisibleChunks(visibleFrom, visibleTo);
+        var startLine = this._textChunks[result.start].startLine;
+        var endLine = this._textChunks[result.end - 1].startLine + this._textChunks[result.end - 1].linesCount;
+        this._paintLines(startLine, endLine + 1);
+    },
+
     /**
      * @param {string} regex
      * @param {string} cssClass
@@ -1474,6 +1500,8 @@ WebInspector.TextEditorMainPanel.prototype = {
 
     wasShown: function()
     {
+        WebInspector.settings.showWhitespaceInEditor.addChangeListener(this._handleShowWhitespaceInEditorChange);
+
         this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
         document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);
 
@@ -1483,6 +1511,8 @@ WebInspector.TextEditorMainPanel.prototype = {
 
     willHide: function()
     {
+        WebInspector.settings.showWhitespaceInEditor.removeChangeListener(this._handleShowWhitespaceInEditorChange);
+
         document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
         delete this._boundSelectionChangeListener;
 
@@ -1970,8 +2000,9 @@ WebInspector.TextEditorMainPanel.prototype = {
      * @param {Element} lineRow
      * @param {string} line
      * @param {Array.<{startColumn: number, endColumn: number, token: ?string}>} ranges
+     * @param {boolean=} splitWhitespaceSequences
      */
-    _renderRanges: function(lineRow, line, ranges)
+    _renderRanges: function(lineRow, line, ranges, splitWhitespaceSequences)
     {
         var decorationsElement = lineRow.decorationsElement;
 
@@ -1993,12 +2024,15 @@ WebInspector.TextEditorMainPanel.prototype = {
         for(var i = 0; i < ranges.length; i++) {
             var rangeStart = ranges[i].startColumn;
             var rangeEnd = ranges[i].endColumn;
-            var cssClass = ranges[i].token ? "webkit-" + ranges[i].token : "";
 
             if (plainTextStart < rangeStart) {
                 this._insertTextNodeBefore(lineRow, decorationsElement, line.substring(plainTextStart, rangeStart));
             }
-            this._insertSpanBefore(lineRow, decorationsElement, line.substring(rangeStart, rangeEnd + 1), cssClass);
+
+            if (splitWhitespaceSequences && ranges[i].token === "whitespace")
+                this._renderWhitespaceCharsWithFixedSizeSpans(lineRow, decorationsElement, rangeEnd - rangeStart + 1);
+            else
+                this._insertSpanBefore(lineRow, decorationsElement, line.substring(rangeStart, rangeEnd + 1), ranges[i].token ? "webkit-" + ranges[i].token : "");
             plainTextStart = rangeEnd + 1;
         }
         if (plainTextStart < line.length) {
@@ -2006,6 +2040,20 @@ WebInspector.TextEditorMainPanel.prototype = {
         }
     },
 
+    /**
+     * @param {Element} lineRow
+     * @param {Element} decorationsElement
+     * @param {number} length
+     */
+    _renderWhitespaceCharsWithFixedSizeSpans: function(lineRow, decorationsElement, length)
+    {
+        for (var whitespaceLength = 16; whitespaceLength > 0; whitespaceLength >>= 1) {
+            var cssClass = "webkit-whitespace webkit-whitespace-" + whitespaceLength;
+            for (; length >= whitespaceLength; length -= whitespaceLength)
+                this._insertSpanBefore(lineRow, decorationsElement, WebInspector.TextEditorMainPanel._ConsecutiveWhitespaceChars[whitespaceLength], cssClass);
+        }
+    },
+
     /**
      * @param {Element} lineRow
      * @param {Array.<WebInspector.TextEditorMainPanel.LineOverlayHighlight>} overlayHighlight
@@ -2022,7 +2070,7 @@ WebInspector.TextEditorMainPanel.prototype = {
 
             var line = this._textModel.line(lineNumber);
             var ranges = syntaxHighlight.ranges;
-            this._renderRanges(lineRow, line, ranges);
+            this._renderRanges(lineRow, line, ranges, this._showWhitespace);
 
             if (overlayHighlight)
                 for(var i = 0; i < overlayHighlight.length; ++i)
index ea0186a5530c1ccf65af44e204063bdda5093d2c..9352204a1ecccd7b9cd264aeb53baae0307b2027 100644 (file)
@@ -111,6 +111,7 @@ WebInspector.Settings = function()
     this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
     this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
     this.showNativeSnapshotUninstrumentedSize = this.createSetting("showNativeSnapshotUninstrumentedSize", false);
+    this.showWhitespaceInEditor = this.createSetting("showWhitespaceInEditor", false);
     this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
     this.textEditorIndent = this.createSetting("textEditorIndent", "    ");
     this.lastDockState = this.createSetting("lastDockState", "");
index 6ef2a86df9947f33dd0e9ea048a864d58b9729c5..657acce5586a73098fbc864720bfb49654963fd3 100644 (file)
@@ -307,6 +307,7 @@ WebInspector.GenericSettingsTab = function()
 
     p = this._appendSection(WebInspector.UIString("Sources"));
     p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Search in content scripts"), WebInspector.settings.searchInContentScripts));
+    p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Show whitespace"), WebInspector.settings.showWhitespaceInEditor));
     p.appendChild(this._createCheckboxSetting(WebInspector.UIString("Enable source maps"), WebInspector.settings.sourceMapsEnabled));
     if (WebInspector.experimentsSettings.isEnabled("sass"))
         p.appendChild(this._createCSSAutoReloadControls());
index 81897d8d43d1ee73fa17fdc45d2d188536708b84..122ae32ccc450f55f7ffa729a0926ed144f4261f 100644 (file)
     color: black;
 }
 
+.webkit-whitespace-1::before {
+    content: "·";
+}
+
+.webkit-whitespace-2::before {
+    content: "··";
+}
+
+.webkit-whitespace-4::before {
+    content: "····";
+}
+
+.webkit-whitespace-8::before {
+    content: "········";
+}
+
+.webkit-whitespace-16::before {
+    content: "················";
+}
+
+.webkit-whitespace::before {
+    position: absolute;
+    color: rgb(175, 175, 175);
+}
+
 .webkit-html-comment {
     /* Keep this in sync with view-source.css (.webkit-html-comment) */
     color: rgb(35, 110, 37);