Changeset 140556 in webkit


Ignore:
Timestamp:
Jan 23, 2013 11:10:03 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: speedup highlight regex API in DefaultTextEditor
https://bugs.webkit.org/show_bug.cgi?id=107238

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

Source/WebCore:

Move overlay highlight measurement (highlight regex API) from DefaultTextEditor._paintLine
method to the DefaultTextEditor._paintLines method which allows to relayout dom only
once. This is a significant improvement to the current state of the
art which does relayout on each regex occurence.
In addition, use "left" css attribute instead of "margin-left": this
way it will be possible to avoid an unnecessary relayouting during
appending overlay highlight.

No new tests: no change in behaviour.

  • inspector/front-end/DefaultTextEditor.js:

(WebInspector.TextEditorMainPanel.prototype.markAndRevealRange):
(WebInspector.TextEditorMainPanel.prototype._paintLines):
(WebInspector.TextEditorMainPanel.prototype._measureRegexHighlight):
(WebInspector.TextEditorMainPanel.prototype._measureSpans):
(WebInspector.TextEditorMainPanel.prototype._appendOverlayHighlight):
(WebInspector.TextEditorMainPanel.prototype._paintLine):
(WebInspector.TextEditorMainPanel.ElementMetrics):
(WebInspector.TextEditorMainPanel.LineOverlayHighlight):
(WebInspector.TextEditorMainChunk.prototype.expand):

LayoutTests:

Corrected layout test expectations to correspond to refactoring.

  • inspector/editor/text-editor-highlight-regexp-expected.txt:
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r140550 r140556  
     12013-01-23  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: speedup highlight regex API in DefaultTextEditor
     4        https://bugs.webkit.org/show_bug.cgi?id=107238
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Corrected layout test expectations to correspond to refactoring.
     9
     10        * inspector/editor/text-editor-highlight-regexp-expected.txt:
     11
    1122013-01-23  Manuel Rego Casasnovas  <rego@igalia.com>
    213
  • trunk/LayoutTests/inspector/editor/text-editor-highlight-regexp-expected.txt

    r139980 r140556  
    1818<div class="inner-container" tabindex="0">
    1919<div class="webkit-line-content">foo();</div>
    20 <div class="webkit-line-content">foo_1; foor; foo_;<span class="some-css-class text-editor-overlay-highlight" style="margin-left: -127px; width: 37px;">&nbsp;</span><span class="some-css-class text-editor-overlay-highlight" style="margin-left: -36px; width: 37px;">&nbsp;</span></div>
     20<div class="webkit-line-content">foo_1; foor; foo_;<span class="some-css-class text-editor-overlay-highlight" style="left: -1px; width: 37px;"> </span><span class="some-css-class text-editor-overlay-highlight" style="left: 90px; width: 37px;"> </span></div>
    2121<div class="webkit-line-content">foo_</div>
    2222<div class="webkit-line-content">global_foo</div>
    2323<div class="webkit-line-content">global_foo2</div>
    24 <div class="webkit-line-content">some_other_foo_X<span class="some-css-class text-editor-overlay-highlight" style="margin-left: -36px; width: 37px;">&nbsp;</span></div></div>
     24<div class="webkit-line-content">some_other_foo_X<span class="some-css-class text-editor-overlay-highlight" style="left: 76px; width: 37px;"> </span></div></div>
    2525
    2626Remove highlight for regexp /foo_./
  • trunk/Source/WebCore/ChangeLog

    r140554 r140556  
     12013-01-23  Andrey Lushnikov  <lushnikov@chromium.org>
     2
     3        Web Inspector: speedup highlight regex API in DefaultTextEditor
     4        https://bugs.webkit.org/show_bug.cgi?id=107238
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Move overlay highlight measurement (highlight regex API) from DefaultTextEditor._paintLine
     9        method to the DefaultTextEditor._paintLines method which allows to relayout dom only
     10        once. This is a significant improvement to the current state of the
     11        art which does relayout on each regex occurence.
     12        In addition, use "left" css attribute instead of "margin-left": this
     13        way it will be possible to avoid an unnecessary relayouting during
     14        appending overlay highlight.
     15
     16        No new tests: no change in behaviour.
     17
     18        * inspector/front-end/DefaultTextEditor.js:
     19        (WebInspector.TextEditorMainPanel.prototype.markAndRevealRange):
     20        (WebInspector.TextEditorMainPanel.prototype._paintLines):
     21        (WebInspector.TextEditorMainPanel.prototype._measureRegexHighlight):
     22        (WebInspector.TextEditorMainPanel.prototype._measureSpans):
     23        (WebInspector.TextEditorMainPanel.prototype._appendOverlayHighlight):
     24        (WebInspector.TextEditorMainPanel.prototype._paintLine):
     25        (WebInspector.TextEditorMainPanel.ElementMetrics):
     26        (WebInspector.TextEditorMainPanel.LineOverlayHighlight):
     27        (WebInspector.TextEditorMainChunk.prototype.expand):
     28
    1292013-01-23  Ojan Vafai  <ojan@chromium.org>
    230
  • trunk/Source/WebCore/inspector/front-end/DefaultTextEditor.js

    r140538 r140556  
    15671567            this.revealLine(range.startLine);
    15681568            var chunk = this.makeLineAChunk(range.startLine);
    1569             this._paintLine(chunk.element);
     1569            this._paintLines(chunk.startLine, chunk.startLine + 1);
    15701570            if (this._markedRangeElement)
    15711571                this._markedRangeElement.scrollIntoViewIfNeeded();
     
    17941794        var chunk;
    17951795        var selection;
     1796        var lineRows = [];
    17961797        for (var lineNumber = fromLine; lineNumber < toLine; ++lineNumber) {
    17971798            if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
     
    18021803            if (restoreSelection && !selection)
    18031804                selection = this.selection();
    1804             this._paintLine(lineRow);
    1805         }
     1805            lineRows.push(lineRow);
     1806        }
     1807
     1808        var highlight = {};
     1809        this.beginDomUpdates();
     1810        for(var regexString in this._highlightRegexs) {
     1811            var regexHighlightDescriptor = this._highlightRegexs[regexString];
     1812            this._measureRegexHighlight(highlight, lineRows, regexHighlightDescriptor.regex, regexHighlightDescriptor.cssClass);
     1813        }
     1814
     1815        for(var i = 0; i < lineRows.length; ++i)
     1816            this._paintLine(lineRows[i], highlight[lineRows[i].lineNumber]);
     1817
     1818        this.endDomUpdates();
    18061819
    18071820        if (restoreSelection)
     
    18281841
    18291842    /**
     1843     * @param {Object.<number, Array.<WebInspector.TextEditorMainPanel.LineOverlayHighlight>>} highlight
     1844     * @param {Array.<Element>} lineRows
     1845     * @param {RegExp} regex
     1846     * @param {string} cssClass
     1847     */
     1848    _measureRegexHighlight: function(highlight, lineRows, regex, cssClass)
     1849    {
     1850        var rowsToMeasure = [];
     1851        for(var i = 0; i < lineRows.length; ++i) {
     1852            var lineRow = lineRows[i];
     1853            var line = this._textModel.line(lineRow.lineNumber);
     1854            var ranges = this._findRegexOccurrences(line, regex);
     1855            if (ranges.length === 0)
     1856                continue;
     1857
     1858            this._renderRanges(lineRow, line, ranges);
     1859            rowsToMeasure.push(lineRow);
     1860        }
     1861
     1862        for(var i = 0; i < rowsToMeasure.length; ++i) {
     1863            var lineRow = rowsToMeasure[i];
     1864            var lineNumber = lineRow.lineNumber;
     1865            var metrics = this._measureSpans(lineRow);
     1866
     1867            if (!highlight[lineNumber])
     1868                highlight[lineNumber] = [];
     1869
     1870            highlight[lineNumber].push(new WebInspector.TextEditorMainPanel.LineOverlayHighlight(metrics, cssClass));
     1871        }
     1872    },
     1873
     1874    /**
    18301875     * @param {Element} lineRow
    1831      * @param {string} line
    1832      * @param {RegExp} regex
    1833      * @return {Array.<{left: number, width: number}>}
    1834      */
    1835     _measureRegex: function(lineRow, line, regex)
    1836     {
    1837         var ranges = this._findRegexOccurrences(line, regex);
    1838         if (ranges.length === 0)
    1839             return [];
    1840 
    1841         this._renderRanges(lineRow, line, ranges);
     1876     * @return {Array.<WebInspector.TextEditorMainPanel.ElementMetrics>}
     1877     */
     1878    _measureSpans: function(lineRow)
     1879    {
    18421880        var spans = lineRow.getElementsByTagName("span");
    1843         if (WebInspector.debugDefaultTextEditor)
    1844             console.assert(spans.length === ranges.length, "Ranges number: " + ranges.length + " !== spans number: " + spans.length);
    1845 
    18461881        var metrics = [];
    1847         for(var i = 0; i < ranges.length; ++i)
    1848             metrics.push({
    1849                 left: spans[i].offsetLeft,
    1850                 width: spans[i].offsetWidth
    1851             });
     1882        for(var i = 0; i < spans.length; ++i)
     1883            metrics.push(new WebInspector.TextEditorMainPanel.ElementMetrics(spans[i]));
    18521884        return metrics;
    18531885    },
     
    18551887    /**
    18561888     * @param {Element} lineRow
    1857      * @param {Array.<{offsetLeft: number, offsetTop: number, offsetWidth: number, offsetHeight: number}>} metrics
    1858      * @param {string} cssClass
    1859      */
    1860     _appendOverlayHighlight: function(lineRow, metrics, cssClass)
     1889     * @param {WebInspector.TextEditorMainPanel.LineOverlayHighlight} highlight
     1890     */
     1891    _appendOverlayHighlight: function(lineRow, highlight)
    18611892    {
    18621893        const extraWidth = 1;
     1894        var metrics = highlight.metrics;
     1895        var cssClass = highlight.cssClass;
    18631896        for(var i = 0; i < metrics.length; ++i) {
    1864             var highlight = document.createElement("span");
    1865             highlight.addStyleClass(cssClass);
    1866             lineRow.appendChild(highlight);
    1867 
    1868             highlight.style.marginLeft = (metrics[i].left - highlight.offsetLeft - extraWidth) + "px";
    1869             highlight.style.width = (metrics[i].width + extraWidth * 2) + "px";
    1870             highlight.innerHTML = "&nbsp;";
    1871             highlight.addStyleClass("text-editor-overlay-highlight");
     1897            var highlightSpan = document.createElement("span");
     1898            highlightSpan.addStyleClass(cssClass);
     1899            highlightSpan.style.left = (metrics[i].left - extraWidth) + "px";
     1900            highlightSpan.style.width = (metrics[i].width + extraWidth * 2) + "px";
     1901            highlightSpan.textContent = " ";
     1902            highlightSpan.addStyleClass("text-editor-overlay-highlight");
     1903            lineRow.appendChild(highlightSpan);
    18721904        }
    18731905    },
     
    19151947    /**
    19161948     * @param {Element} lineRow
    1917      */
    1918     _paintLine: function(lineRow)
     1949     * @param {Array.<WebInspector.TextEditorMainPanel.LineOverlayHighlight>} overlayHighlight
     1950     */
     1951    _paintLine: function(lineRow, overlayHighlight)
    19191952    {
    19201953        var lineNumber = lineRow.lineNumber;
     
    19221955        this.beginDomUpdates();
    19231956        try {
    1924             var highlight = this._textModel.getAttribute(lineNumber, "highlight");
    1925             if (!highlight)
     1957            var syntaxHighlight = this._textModel.getAttribute(lineNumber, "highlight");
     1958            if (!syntaxHighlight)
    19261959                return;
    19271960
    19281961            var line = this._textModel.line(lineNumber);
    1929 
    1930             var metrics = [];
    1931             var cssClasses = [];
    1932             for(var key in this._highlightRegexs) {
    1933                 var value = this._highlightRegexs[key];
    1934                 metrics.push(this._measureRegex(lineRow, line, value.regex));
    1935                 cssClasses.push(value.cssClass);
    1936             }
    1937 
    1938             var ranges = highlight.ranges;
     1962            var ranges = syntaxHighlight.ranges;
    19391963            this._renderRanges(lineRow, line, ranges);
    19401964
    1941             for(var i = 0; i < metrics.length; ++i)
    1942                 this._appendOverlayHighlight(lineRow, metrics[i], cssClasses[i]);
     1965            if (overlayHighlight)
     1966                for(var i = 0; i < overlayHighlight.length; ++i)
     1967                    this._appendOverlayHighlight(lineRow, overlayHighlight[i]);
    19431968        } finally {
    19441969            if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
     
    26382663/**
    26392664 * @constructor
     2665 * @param {Element} element
     2666 */
     2667WebInspector.TextEditorMainPanel.ElementMetrics = function(element)
     2668{
     2669    this.width = element.offsetWidth;
     2670    this.left = element.offsetLeft;
     2671}
     2672
     2673/**
     2674 * @constructor
     2675 * @param {Array.<WebInspector.TextEditorMainPanel.ElementMetrics>} metrics
     2676 * @param {string} cssClass
     2677 */
     2678WebInspector.TextEditorMainPanel.LineOverlayHighlight = function(metrics, cssClass)
     2679{
     2680    this.metrics = metrics;
     2681    this.cssClass = cssClass;
     2682}
     2683
     2684/**
     2685 * @constructor
    26402686 * @param {WebInspector.TextEditorChunkedPanel} chunkedPanel
    26412687 * @param {number} startLine
     
    27562802
    27572803        if (this.linesCount === 1) {
    2758             this._chunkedPanel._paintLine(this.element);
     2804            this._chunkedPanel._paintLines(this.startLine, this.startLine + 1);
    27592805            return;
    27602806        }
Note: See TracChangeset for help on using the changeset viewer.