[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

pfeldman at chromium.org pfeldman at chromium.org
Thu Apr 8 01:03:27 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 4b35dc006eafd9fec17ff07c07fd60b1c08ad303
Author: pfeldman at chromium.org <pfeldman at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 13 15:24:14 2010 +0000

    2010-01-13  Pavel Feldman  <pfeldman at chromium.org>
    
            Reviewed by Timothy Hatcher.
    
            Web Inspector: Scrolling editor to the 20Kth line is not smooth.
    
            https://bugs.webkit.org/show_bug.cgi?id=33587
    
            * inspector/front-end/TextEditor.js:
            (WebInspector.TextEditor):
            (WebInspector.TextEditor.prototype._textChanged):
            (WebInspector.TextEditor.prototype._highlightChanged):
            (WebInspector.TextEditor.prototype._paintLinesContinuation):
            * inspector/front-end/TextEditorHighlighter.js:
            (WebInspector.TextEditorHighlighter):
            (WebInspector.TextEditorHighlighter.prototype.highlight):
            (WebInspector.TextEditorHighlighter.prototype._highlightInChunks):
            (WebInspector.TextEditorHighlighter.prototype.updateHighlight):
            (WebInspector.TextEditorHighlighter.prototype._highlightLines):
            (WebInspector.TextEditorHighlighter.prototype._lex):
            * inspector/front-end/TextEditorModel.js:
            (WebInspector.TextEditorModel.prototype._setLine):
            (WebInspector.TextEditorModel.prototype.setAttribute):
            (WebInspector.TextEditorModel.prototype.getAttribute):
            (WebInspector.TextEditorModel.prototype.removeAttribute):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53184 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1d0b578..bade55a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2010-01-13  Pavel Feldman  <pfeldman at chromium.org>
+
+        Reviewed by Timothy Hatcher.
+
+        Web Inspector: Scrolling editor to the 20Kth line is not smooth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=33587
+
+        * inspector/front-end/TextEditor.js:
+        (WebInspector.TextEditor):
+        (WebInspector.TextEditor.prototype._textChanged):
+        (WebInspector.TextEditor.prototype._highlightChanged):
+        (WebInspector.TextEditor.prototype._paintLinesContinuation):
+        * inspector/front-end/TextEditorHighlighter.js:
+        (WebInspector.TextEditorHighlighter):
+        (WebInspector.TextEditorHighlighter.prototype.highlight):
+        (WebInspector.TextEditorHighlighter.prototype._highlightInChunks):
+        (WebInspector.TextEditorHighlighter.prototype.updateHighlight):
+        (WebInspector.TextEditorHighlighter.prototype._highlightLines):
+        (WebInspector.TextEditorHighlighter.prototype._lex):
+        * inspector/front-end/TextEditorModel.js:
+        (WebInspector.TextEditorModel.prototype._setLine):
+        (WebInspector.TextEditorModel.prototype.setAttribute):
+        (WebInspector.TextEditorModel.prototype.getAttribute):
+        (WebInspector.TextEditorModel.prototype.removeAttribute):
+
 2010-01-13  Jocelyn Turcotte  <jocelyn.turcotte at nokia.com>
 
         Reviewed by Simon Hausmann.
diff --git a/WebCore/inspector/front-end/TextEditor.js b/WebCore/inspector/front-end/TextEditor.js
index adacc8d..38dc3d0 100644
--- a/WebCore/inspector/front-end/TextEditor.js
+++ b/WebCore/inspector/front-end/TextEditor.js
@@ -31,7 +31,7 @@
 WebInspector.TextEditor = function(platform)
 {
     this._textModel = new WebInspector.TextEditorModel(this._textChanged.bind(this));
-    this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel);
+    this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel, this._highlightChanged.bind(this));
 
     this.element = document.createElement("div");
     this.element.className = "text-editor";
@@ -183,7 +183,11 @@ WebInspector.TextEditor.prototype = {
             // Lines shifted, invalidate all under start line. Also clear lines that now are outside model range.
             this._invalidateLines(newRange.startLine, this._textModel.linesCount + Math.max(0, oldRange.endLine - newRange.endLine));
 
-        this._invalidateHighlight(newRange.startLine);
+        if (this._highlightingEnabled) {
+            var lastVisibleLine = Math.min(this._textModel.linesCount, this._offsetToLineNumber(this._scrollTop + this._canvas.height) + 1);
+            this._highlighter.updateHighlight(newRange.startLine, lastVisibleLine);
+        }
+
         this._updateSize(newRange.startLine, Math.max(newRange.endLine, oldRange.endLine));
         if (oldRange.linesCount !== newRange.linesCount) {
             // Invalidate offset cache.
@@ -208,6 +212,12 @@ WebInspector.TextEditor.prototype = {
         this._paint();
     },
 
+    _highlightChanged: function(fromLine, toLine)
+    {
+        this._invalidateLines(fromLine, toLine + 1);
+        this._paint();
+    },
+
     _updateSize: function(startLine, endLine)
     {
         var newLineNumberDigits = this._decimalDigits(this._textModel.linesCount);
@@ -320,12 +330,12 @@ WebInspector.TextEditor.prototype = {
         }
         lastLine = Math.min(lastLine, this._textModel.linesCount);
 
+        if (this._highlightingEnabled)
+            this._highlighter.highlight(lastLine);
+
         if (this._selection.startLine === this._selection.endLine && firstLine <= this._selection.startLine && this._selection.startLine < lastLine)
             this._paintCurrentLine(this._selection.startLine);
 
-        if (this._highlightingEnabled)
-            this._highlighter.highlight(firstLine, lastLine);
-
         this._paintSelection(firstLine, lastLine);
 
         for (var i = firstLine; i < lastLine; ++i) {
@@ -338,10 +348,10 @@ WebInspector.TextEditor.prototype = {
                 continue;
             }
 
-            var attributes = this._textModel.getAttributes(i, "highlight");
+            var highlighterState = this._textModel.getAttribute(i, "highlighter-state");
             var plainTextStart = -1;
             for (var j = 0; j < line.length;) {
-                var attribute = attributes && attributes[j];
+                var attribute = highlighterState && highlighterState.attributes[j];
                 if (!attribute || !attribute.style) {
                     if (plainTextStart === -1)
                         plainTextStart = j;
@@ -630,18 +640,6 @@ WebInspector.TextEditor.prototype = {
         return { line: line, column: column };
     },
 
-    _invalidateHighlight: function(startLine)
-    {
-        if (!this._highlightingEnabled)
-            return;
-        var firstVisibleLine = Math.max(0, this._offsetToLineNumber(this._scrollTop) - 1);
-        var lastVisibleLine = Math.min(this._textModel.linesCount, this._offsetToLineNumber(this._scrollTop + this._canvas.height) + 1);
-
-        var damage = this._highlighter.highlight(startLine, lastVisibleLine);
-        for (var line in damage)
-            this._invalidateLines(line, parseInt(line) + 1);
-    },
-
     _paintSelection: function(firstLine, lastLine)
     {
         if (this._selection.isEmpty())
diff --git a/WebCore/inspector/front-end/TextEditorHighlighter.js b/WebCore/inspector/front-end/TextEditorHighlighter.js
index 48dcfc9..2bfde24 100644
--- a/WebCore/inspector/front-end/TextEditorHighlighter.js
+++ b/WebCore/inspector/front-end/TextEditorHighlighter.js
@@ -29,7 +29,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WebInspector.TextEditorHighlighter = function(textModel)
+WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
 {
     this._textModel = textModel;
     this._tokenizer = new WebInspector.JavaScriptTokenizer();
@@ -40,62 +40,132 @@ WebInspector.TextEditorHighlighter = function(textModel)
     this._styles["regex"] = "rgb(196, 26, 22)";
     this._styles["keyword"] = "rgb(170, 13, 145)";
     this._styles["number"] = "rgb(28, 0, 207)";
+
+    this._damageCallback = damageCallback;    
 }
 
 WebInspector.TextEditorHighlighter.prototype = {
-    highlight: function(startLine, endLine)
+    highlight: function(endLine)
     {
-        // Rewind to the last highlighted line to gain proper highlighter context.
-        while (startLine > 0 && !this._textModel.getAttribute(startLine - 1, 0, "highlighter-state"))
+        // First check if we have work to do.
+        var state = this._textModel.getAttribute(endLine - 1, "highlighter-state")
+        if (state && !state.outOfDate) {
+            // Last line is highlighted, just exit.
+            return;
+        }
+
+        this._requestedEndLine = endLine;
+
+        if (this._highlightTimer) {
+            // There is a timer scheduled, it will catch the new job based on the new endLine set.
+            return;
+        }
+
+        // We will be highlighting. First rewind to the last highlighted line to gain proper highlighter context.
+        var startLine = endLine;
+        while (startLine > 0) {
+            var state = this._textModel.getAttribute(startLine - 1, "highlighter-state");
+            if (state && !state.outOfDate)
+                break;
             startLine--;
+        }
+
+        // Do small highlight synchronously. This will provide instant highlight on PageUp / PageDown, gentle scrolling.
+        var toLine = Math.min(startLine + 200, endLine);
+        this._highlightLines(startLine, toLine);
+
+        // Schedule tail highlight if necessary.
+        if (endLine > toLine)
+            this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, endLine), 100);
+    },
+
+    _highlightInChunks: function(startLine, endLine)
+    {
+        delete this._highlightTimer;
+
+        // First we always check if we have work to do. Could be that user scrolled back and we can quit.
+        var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlighter-state");
+        if (state && !state.outOfDate)
+            return;
+
+        if (this._requestedEndLine !== endLine) {
+            // User keeps updating the job in between of our timer ticks. Just reschedule self, don't eat CPU (they must be scrolling).
+            this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 200);
+            return;
+        }
+
+        // Highlight 500 lines chunk.
+        var toLine = Math.min(startLine + 500, this._requestedEndLine);
+        this._highlightLines(startLine, toLine);
+
+        // Schedule tail highlight if necessary.
+        if (toLine < this._requestedEndLine)
+            this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, this._requestedEndLine), 10);
+    },
+
+    updateHighlight: function(startLine, endLine)
+    {
+        // Start line was edited, we should highlight everything until endLine synchronously.
+        var state = this._textModel.getAttribute(startLine, "highlighter-state");
+        if (!state || state.outOfDate) {
+            // Highlighter did not reach this point yet, nothing to update. It will reach it on subsequent timer tick and do the job.
+            return;
+        }
+
+        var restored = this._highlightLines(startLine, endLine);
 
+        // Set invalidated flag to the subsequent lines.
+        for (var i = endLine; i < this._textModel.linesCount; ++i) {
+            var highlighterState = this._textModel.getAttribute(i, "highlighter-state");
+            if (highlighterState)
+                highlighterState.outOfDate = !restored;
+            else
+                return;
+        }
+    },
+
+    _highlightLines: function(startLine, endLine)
+    {
         // Restore highlighter context taken from previous line.
-        var state = this._textModel.getAttribute(startLine - 1, 0, "highlighter-state");
-         if (state)
-             this._tokenizer.condition = state.postCondition;
-         else
-             this._tokenizer.condition = this._tokenizer.initialCondition;
-        // Each line has associated state attribute with pre- and post-highlighter conditions.
-        // Highlight lines from range until we find line precondition matching highlighter state.
-        var damage = {};
-        for (var i = startLine; i < endLine; ++i) {
-            state = this._textModel.getAttribute(i, 0, "highlighter-state");
-            if (state && state.preCondition === this._tokenizer.condition) {
-                // Following lines are up to date, no need re-highlight.
-                this._tokenizer.condition = state.postCondition;
-                continue;
-            }
+        var state = this._textModel.getAttribute(startLine - 1, "highlighter-state");
+        if (state)
+            this._tokenizer.condition = state.postCondition;
+        else
+            this._tokenizer.condition = this._tokenizer.initialCondition;
 
-            damage[i] = true;
+        var damagedFrom = startLine;
+        var damagedTo = startLine;
+        for (var i = startLine; i < endLine; ++i) {
+            damagedTo = i;
 
             state = {};
             state.preCondition = this._tokenizer.condition;
+            state.attributes = {};
 
-            this._textModel.removeAttributes(i, "highlight");
-            this._lex(this._textModel.line(i), i);
+            this._lex(this._textModel.line(i), i, state.attributes);
 
             state.postCondition = this._tokenizer.condition;
-            this._textModel.addAttribute(i, 0, "highlighter-state", state);
-        }
-
-        state = this._textModel.getAttribute(endLine, 0, "highlighter-state");
+            this._textModel.setAttribute(i, "highlighter-state", state);
 
-        if (state && state.preCondition !== this._tokenizer.condition) {
-            // Requested highlight range is over, but we did not recover. Invalidate tail highlighting.
-            for (var i = endLine; i < this._textModel.linesCount; ++i)
-                this._textModel.removeAttributes(i, "highlighter-state");
+            var nextLineState = this._textModel.getAttribute(i + 1, "highlighter-state");
+            if (nextLineState && nextLineState.preCondition === state.postCondition) {
+                // Following lines are up to date, no need re-highlight.
+                this._damageCallback(damagedFrom, damagedTo);
+                return true;
+            }
         }
-        return damage;
+        this._damageCallback(damagedFrom, damagedTo);
+        return false;
     },
 
-    _lex: function(line, lineNumber) {
+    _lex: function(line, lineNumber, attributes) {
          this._tokenizer.line = line;
          var column = 0;
          do {
              var newColumn = this._tokenizer.nextToken(column);
              var tokenType = this._tokenizer.tokenType;
              if (tokenType)
-                 this._textModel.addAttribute(lineNumber, column, "highlight", { length: newColumn - column, style: this._styles[tokenType] });
+                 attributes[column] = { length: newColumn - column, style: this._styles[tokenType] };
              column = newColumn;
          } while (column < line.length)
     }
diff --git a/WebCore/inspector/front-end/TextEditorModel.js b/WebCore/inspector/front-end/TextEditorModel.js
index 5c5a74e..675b0cf 100644
--- a/WebCore/inspector/front-end/TextEditorModel.js
+++ b/WebCore/inspector/front-end/TextEditorModel.js
@@ -136,7 +136,6 @@ WebInspector.TextEditorModel.prototype = {
     _setLine: function(lineNumber, text)
     {
         this._lines[lineNumber] = text;
-        delete this._attributes[lineNumber];
     },
 
     _removeLines: function(fromLine, count)
@@ -186,34 +185,23 @@ WebInspector.TextEditorModel.prototype = {
         return clip.join("\n");
     },
 
-    addAttribute: function(line, column, name, value)
+    setAttribute: function(line, name, value)
     {
         var attrs = this._attributes[line];
         if (!attrs) {
             attrs = [];
             this._attributes[line] = attrs;
         }
-        var family = attrs[name];
-        if (!family) {
-            family = [];
-            attrs[name] = family;
-        }
-        family[column] = value;
-    },
-
-    getAttribute: function(line, column, name)
-    {
-        var family = this.getAttributes(line, name);
-        return family ? family[column] : null;
+        attrs[name] = value;
     },
 
-    getAttributes: function(line, name)
+    getAttribute: function(line, name)
     {
         var attrs = this._attributes[line];
         return attrs ? attrs[name] : null;
     },
 
-    removeAttributes: function(line, name)
+    removeAttribute: function(line, name)
     {
         var attrs = this._attributes[line];
         if (attrs)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list