Title: [139844] trunk
Revision
139844
Author
[email protected]
Date
2013-01-16 00:48:56 -0800 (Wed, 16 Jan 2013)

Log Message

Web Inspector: highlight regexp API for DefaultTextEditor
https://bugs.webkit.org/show_bug.cgi?id=106801

Patch by Andrey Lushnikov <[email protected]> on 2013-01-16
Reviewed by Pavel Feldman.

Source/WebCore:

Add highlightRegexp and removeRegexpHighlight methods to DefaultTextEditor that highlight
all occurrences of given regexp in text with given css class.
Highlight is done via spans positioned absolutely over the regexp occurences in text.

Test: inspector/editor/text-editor-highlight-regexp.html

* inspector/front-end/DefaultTextEditor.js:
(WebInspector.DefaultTextEditor.prototype.highlightRegex):
(WebInspector.DefaultTextEditor.prototype.removeRegexHighlight):
(WebInspector.TextEditorMainPanel):
(WebInspector.TextEditorMainPanel.prototype.highlightRegex):
(WebInspector.TextEditorMainPanel.prototype.removeRegexHighlight):
(WebInspector.TextEditorMainPanel.prototype._repaintVisibleChunks):
(WebInspector.TextEditorMainPanel.prototype._findRegexOccurrences):
(WebInspector.TextEditorMainPanel.prototype._measureRegex):
(WebInspector.TextEditorMainPanel.prototype._appendOverlayHighlight):
(WebInspector.TextEditorMainPanel.prototype._paintLine):
* inspector/front-end/TextEditor.js:
(WebInspector.TextEditor.prototype.highlightRegex):
(WebInspector.TextEditor.prototype.removeRegexHighlight):
* inspector/front-end/textEditor.css:
(.text-editor-overlay-highlight):
(.debug-fadeout):

LayoutTests:

New layout test to verify DefaultTextEditor highlight regexp API.

* inspector/editor/text-editor-highlight-regexp-expected.txt: Added.
* inspector/editor/text-editor-highlight-regexp.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (139843 => 139844)


--- trunk/LayoutTests/ChangeLog	2013-01-16 08:23:43 UTC (rev 139843)
+++ trunk/LayoutTests/ChangeLog	2013-01-16 08:48:56 UTC (rev 139844)
@@ -1,3 +1,15 @@
+2013-01-16  Andrey Lushnikov  <[email protected]>
+
+        Web Inspector: highlight regexp API for DefaultTextEditor
+        https://bugs.webkit.org/show_bug.cgi?id=106801
+
+        Reviewed by Pavel Feldman.
+
+        New layout test to verify DefaultTextEditor highlight regexp API.
+
+        * inspector/editor/text-editor-highlight-regexp-expected.txt: Added.
+        * inspector/editor/text-editor-highlight-regexp.html: Added.
+
 2013-01-15  Tab Atkins  <[email protected]>
 
         Update CSS3 gradient support to the latest spec version

Added: trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp-expected.txt (0 => 139844)


--- trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp-expected.txt	2013-01-16 08:48:56 UTC (rev 139844)
@@ -0,0 +1,35 @@
+Test editor highlight regexp API.
+
+
+Running: testHighlightApi
+
+Before highlight
+
+<div class="inner-container" tabindex="0">
+<div class="webkit-line-content">foo();</div>
+<div class="webkit-line-content">foo_1; foor; foo_;</div>
+<div class="webkit-line-content">foo_</div>
+<div class="webkit-line-content">global_foo</div>
+<div class="webkit-line-content">global_foo2</div>
+<div class="webkit-line-content">some_other_foo_X</div></div>
+
+Add highlight for regexp /foo_./
+
+<div class="inner-container" tabindex="0">
+<div class="webkit-line-content">foo();</div>
+<div class="webkit-line-content">foo_1; foor; foo_;<span class="some-css-class text-editor-overlay-highlight" style="margin-left: -127px; width: 37px; height: 14px;"></span><span class="some-css-class text-editor-overlay-highlight" style="margin-left: -36px; width: 37px; height: 14px;"></span></div>
+<div class="webkit-line-content">foo_</div>
+<div class="webkit-line-content">global_foo</div>
+<div class="webkit-line-content">global_foo2</div>
+<div class="webkit-line-content">some_other_foo_X<span class="some-css-class text-editor-overlay-highlight" style="margin-left: -36px; width: 37px; height: 14px;"></span></div></div>
+
+Remove highlight for regexp /foo_./
+
+<div class="inner-container" tabindex="0">
+<div class="webkit-line-content">foo();</div>
+<div class="webkit-line-content">foo_1; foor; foo_;</div>
+<div class="webkit-line-content">foo_</div>
+<div class="webkit-line-content">global_foo</div>
+<div class="webkit-line-content">global_foo2</div>
+<div class="webkit-line-content">some_other_foo_X</div></div>
+
Property changes on: trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp-expected.txt
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp.html (0 => 139844)


--- trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp.html	2013-01-16 08:48:56 UTC (rev 139844)
@@ -0,0 +1,43 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+
+function test()
+{
+    InspectorTest.runTestSuite([
+        function testHighlightApi(next)
+        {
+            var text = [
+                "foo();",
+                "foo_1; foor; foo_;",
+                "foo_",
+                "global_foo",
+                "global_foo2",
+                "some_other_foo_X"
+            ];
+            var textEditor = InspectorTest.createTestEditor();
+            textEditor.setText(text.join("\n"));
+            InspectorTest.addResult("\nBefore highlight");
+            InspectorTest.addResult(textEditor._mainPanel.element.innerHTML.replace(/<div/g, "\n<div"));
+            textEditor.highlightRegex(/foo_./, "some-css-class");
+            InspectorTest.addResult("\nAdd highlight for regexp /foo_./");
+            InspectorTest.addResult(textEditor._mainPanel.element.innerHTML.replace(/<div/g, "\n<div"));
+            InspectorTest.addResult("\nRemove highlight for regexp /foo_./");
+            textEditor.removeRegexHighlight(/foo_./);
+            InspectorTest.addResult(textEditor._mainPanel.element.innerHTML.replace(/<div/g, "\n<div"));
+            next();
+        },
+    ]);
+}
+
+</script>
+</head>
+
+<body _onload_="runTest()">
+<p>
+Test editor highlight regexp API.
+</p>
+</body>
+</html>
Property changes on: trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (139843 => 139844)


--- trunk/Source/WebCore/ChangeLog	2013-01-16 08:23:43 UTC (rev 139843)
+++ trunk/Source/WebCore/ChangeLog	2013-01-16 08:48:56 UTC (rev 139844)
@@ -1,3 +1,34 @@
+2013-01-16  Andrey Lushnikov  <[email protected]>
+
+        Web Inspector: highlight regexp API for DefaultTextEditor
+        https://bugs.webkit.org/show_bug.cgi?id=106801
+
+        Reviewed by Pavel Feldman.
+
+        Add highlightRegexp and removeRegexpHighlight methods to DefaultTextEditor that highlight
+        all occurrences of given regexp in text with given css class.
+        Highlight is done via spans positioned absolutely over the regexp occurences in text.
+
+        Test: inspector/editor/text-editor-highlight-regexp.html
+
+        * inspector/front-end/DefaultTextEditor.js:
+        (WebInspector.DefaultTextEditor.prototype.highlightRegex):
+        (WebInspector.DefaultTextEditor.prototype.removeRegexHighlight):
+        (WebInspector.TextEditorMainPanel):
+        (WebInspector.TextEditorMainPanel.prototype.highlightRegex):
+        (WebInspector.TextEditorMainPanel.prototype.removeRegexHighlight):
+        (WebInspector.TextEditorMainPanel.prototype._repaintVisibleChunks):
+        (WebInspector.TextEditorMainPanel.prototype._findRegexOccurrences):
+        (WebInspector.TextEditorMainPanel.prototype._measureRegex):
+        (WebInspector.TextEditorMainPanel.prototype._appendOverlayHighlight):
+        (WebInspector.TextEditorMainPanel.prototype._paintLine):
+        * inspector/front-end/TextEditor.js:
+        (WebInspector.TextEditor.prototype.highlightRegex):
+        (WebInspector.TextEditor.prototype.removeRegexHighlight):
+        * inspector/front-end/textEditor.css:
+        (.text-editor-overlay-highlight):
+        (.debug-fadeout):
+
 2013-01-16  Ryosuke Niwa  <[email protected]>
 
         Get rid of Node::createRareData

Modified: trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js (139843 => 139844)


--- trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js	2013-01-16 08:23:43 UTC (rev 139843)
+++ trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js	2013-01-16 08:48:56 UTC (rev 139844)
@@ -110,6 +110,24 @@
 
 WebInspector.DefaultTextEditor.prototype = {
     /**
+     * @param {RegExp} regex
+     * @param {string} cssClass
+     */
+    highlightRegex: function(regex, cssClass)
+    {
+        this._mainPanel.highlightRegex(regex, cssClass);
+    },
+
+    /**
+     * @param {RegExp} regex
+     * @return {boolean}
+     */
+    removeRegexHighlight: function(regex)
+    {
+        return this._mainPanel.removeRegexHighlight(regex);
+    },
+
+    /**
      * @param {string} mimeType
      */
     set mimeType(mimeType)
@@ -1338,11 +1356,52 @@
 
     this._container.addEventListener("focus", this._handleFocused.bind(this), false);
 
+    this._highlightRegexs = {};
+
     this._freeCachedElements();
     this.buildChunks();
 }
 
 WebInspector.TextEditorMainPanel.prototype = {
+    /**
+     * @param {RegExp} regex
+     * @param {string} cssClass
+     */
+    highlightRegex: function(regex, cssClass)
+    {
+        this._highlightRegexs[regex] = {
+            regex: new RegExp(regex.source, "g" + (regex.ignoreCase ? "i" : "")),
+            cssClass: cssClass
+        };
+        this._repaintVisibleChunks();
+    },
+
+    /**
+     * @param {RegExp} regex
+     * @return {boolean}
+     */
+    removeRegexHighlight: function(regex)
+    {
+        var result = delete this._highlightRegexs[regex];
+        this._repaintVisibleChunks();
+        return result;
+    },
+
+    _repaintVisibleChunks: function()
+    {
+        var visibleFrom = this.scrollTop();
+        var visibleTo = visibleFrom + this.clientHeight();
+
+        var visibleChunks = this.findVisibleChunks(visibleFrom, visibleTo);
+        var selection = this.selection();
+
+        for(var i = visibleChunks.start; i < visibleChunks.end; ++i) {
+            var chunk = this._textChunks[i];
+            this._paintLines(chunk._startLine, chunk._startLine + chunk.linesCount);
+        }
+        this._restoreSelection(selection);
+    },
+
     wasShown: function()
     {
         this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
@@ -1864,8 +1923,73 @@
     },
 
     /**
+     * @param {string} line
+     * @param {RegExp} regex
+     * @return {Array.<{startColumn: number, endColumn: number}>}
+     */
+    _findRegexOccurrences: function(line, regex)
+    {
+        var ranges = [];
+        var regexResult;
+        while (regexResult = regex.exec(line)) {
+            ranges.push({
+                startColumn: regexResult.index,
+                endColumn: regexResult.index + regexResult[0].length - 1
+            });
+        }
+        return ranges;
+    },
+
+    /**
      * @param {Element} lineRow
      * @param {string} line
+     * @param {RegExp} regex
+     * @return {Array.<{left: number, width: number, height: number}>}
+     */
+    _measureRegex: function(lineRow, line, regex)
+    {
+        var ranges = this._findRegexOccurrences(line, regex);
+        if (ranges.length === 0)
+            return [];
+
+        this._renderRanges(lineRow, line, ranges);
+        var spans = lineRow.getElementsByTagName("span");
+        if (WebInspector.debugDefaultTextEditor)
+            console.assert(spans.length === ranges.length, "Ranges number: " + ranges.length + " !== spans number: " + spans.length);
+
+        var metrics = [];
+        for(var i = 0; i < ranges.length; ++i)
+            metrics.push({
+                left: spans[i].offsetLeft,
+                width: spans[i].offsetWidth,
+                height: spans[i].offsetHeight
+            });
+        return metrics;
+    },
+
+    /**
+     * @param {Element} lineRow
+     * @param {Array.<{offsetLeft: number, offsetTop: number, offsetWidth: number, offsetHeight: number}>} metrics
+     * @param {string} cssClass
+     */
+    _appendOverlayHighlight: function(lineRow, metrics, cssClass)
+    {
+        const extraWidth = 1;
+        for(var i = 0; i < metrics.length; ++i) {
+            var highlight = document.createElement("span");
+            highlight.addStyleClass(cssClass);
+            lineRow.appendChild(highlight);
+
+            highlight.style.marginLeft = (metrics[i].left - highlight.offsetLeft - extraWidth) + "px";
+            highlight.style.width = (metrics[i].width + extraWidth * 2) + "px";
+            highlight.style.height = metrics[i].height + "px";
+            highlight.addStyleClass("text-editor-overlay-highlight");
+        }
+    },
+
+    /**
+     * @param {Element} lineRow
+     * @param {string} line
      * @param {Array.<{startColumn: number, endColumn: number, cssClass: string}>} ranges
      */
     _renderRanges: function(lineRow, line, ranges)
@@ -1925,8 +2049,20 @@
                 return;
 
             var line = this._textModel.line(lineNumber);
+
+            var metrics = [];
+            var cssClasses = [];
+            for(var key in this._highlightRegexs) {
+                var value = this._highlightRegexs[key];
+                metrics.push(this._measureRegex(lineRow, line, value.regex));
+                cssClasses.push(value.cssClass);
+            }
+
             var ranges = this._highlighter.orderedRangesPerLine(lineNumber);
             this._renderRanges(lineRow, line, ranges);
+
+            for(var i = 0; i < metrics.length; ++i)
+                this._appendOverlayHighlight(lineRow, metrics[i], cssClasses[i]);
         } finally {
             if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
                 this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);

Modified: trunk/Source/WebCore/inspector/front-end/TextEditor.js (139843 => 139844)


--- trunk/Source/WebCore/inspector/front-end/TextEditor.js	2013-01-16 08:23:43 UTC (rev 139843)
+++ trunk/Source/WebCore/inspector/front-end/TextEditor.js	2013-01-16 08:48:56 UTC (rev 139844)
@@ -61,6 +61,18 @@
     defaultFocusedElement: function() { },
 
     /**
+     * @param {RegExp} regex
+     * @param {string} cssClass
+     */
+    highlightRegex: function(regex, cssClass) { },
+
+    /**
+     * @param {RegExp} regex
+     * @return {boolean}
+     */
+    removeRegexHighlight: function(regex) { },
+
+    /**
      * @param {number} lineNumber
      */
     revealLine: function(lineNumber) { },

Modified: trunk/Source/WebCore/inspector/front-end/textEditor.css (139843 => 139844)


--- trunk/Source/WebCore/inspector/front-end/textEditor.css	2013-01-16 08:23:43 UTC (rev 139843)
+++ trunk/Source/WebCore/inspector/front-end/textEditor.css	2013-01-16 08:48:56 UTC (rev 139844)
@@ -30,6 +30,13 @@
     -webkit-user-select: text;
 }
 
+.text-editor-overlay-highlight {
+    position: absolute;
+    pointer-events: none;
+    -webkit-user-select: none;
+    z-index: -1;
+}
+
 .text-editor-contents .inner-container {
     position: absolute;
     top: 0;
@@ -183,6 +190,7 @@
 .debug-fadeout {
     -webkit-animation: "debug-fadeout" 1s 0s;
     border: 1px solid white;
+    margin: -1px;
 }
 
 @-webkit-keyframes debug-fadeout {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to