Changeset 53184 in webkit
- Timestamp:
- Jan 13, 2010 7:24:14 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r53183 r53184 1 2010-01-13 Pavel Feldman <pfeldman@chromium.org> 2 3 Reviewed by Timothy Hatcher. 4 5 Web Inspector: Scrolling editor to the 20Kth line is not smooth. 6 7 https://bugs.webkit.org/show_bug.cgi?id=33587 8 9 * inspector/front-end/TextEditor.js: 10 (WebInspector.TextEditor): 11 (WebInspector.TextEditor.prototype._textChanged): 12 (WebInspector.TextEditor.prototype._highlightChanged): 13 (WebInspector.TextEditor.prototype._paintLinesContinuation): 14 * inspector/front-end/TextEditorHighlighter.js: 15 (WebInspector.TextEditorHighlighter): 16 (WebInspector.TextEditorHighlighter.prototype.highlight): 17 (WebInspector.TextEditorHighlighter.prototype._highlightInChunks): 18 (WebInspector.TextEditorHighlighter.prototype.updateHighlight): 19 (WebInspector.TextEditorHighlighter.prototype._highlightLines): 20 (WebInspector.TextEditorHighlighter.prototype._lex): 21 * inspector/front-end/TextEditorModel.js: 22 (WebInspector.TextEditorModel.prototype._setLine): 23 (WebInspector.TextEditorModel.prototype.setAttribute): 24 (WebInspector.TextEditorModel.prototype.getAttribute): 25 (WebInspector.TextEditorModel.prototype.removeAttribute): 26 1 27 2010-01-13 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> 2 28 -
trunk/WebCore/inspector/front-end/TextEditor.js
r53052 r53184 32 32 { 33 33 this._textModel = new WebInspector.TextEditorModel(this._textChanged.bind(this)); 34 this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel );34 this._highlighter = new WebInspector.TextEditorHighlighter(this._textModel, this._highlightChanged.bind(this)); 35 35 36 36 this.element = document.createElement("div"); … … 184 184 this._invalidateLines(newRange.startLine, this._textModel.linesCount + Math.max(0, oldRange.endLine - newRange.endLine)); 185 185 186 this._invalidateHighlight(newRange.startLine); 186 if (this._highlightingEnabled) { 187 var lastVisibleLine = Math.min(this._textModel.linesCount, this._offsetToLineNumber(this._scrollTop + this._canvas.height) + 1); 188 this._highlighter.updateHighlight(newRange.startLine, lastVisibleLine); 189 } 190 187 191 this._updateSize(newRange.startLine, Math.max(newRange.endLine, oldRange.endLine)); 188 192 if (oldRange.linesCount !== newRange.linesCount) { … … 206 210 this._invalidateLines(oldRange.startLine, oldRange.endLine + 1); 207 211 this._invalidateLines(newRange.startLine, newRange.endLine + 1); 212 this._paint(); 213 }, 214 215 _highlightChanged: function(fromLine, toLine) 216 { 217 this._invalidateLines(fromLine, toLine + 1); 208 218 this._paint(); 209 219 }, … … 321 331 lastLine = Math.min(lastLine, this._textModel.linesCount); 322 332 333 if (this._highlightingEnabled) 334 this._highlighter.highlight(lastLine); 335 323 336 if (this._selection.startLine === this._selection.endLine && firstLine <= this._selection.startLine && this._selection.startLine < lastLine) 324 337 this._paintCurrentLine(this._selection.startLine); 325 326 if (this._highlightingEnabled)327 this._highlighter.highlight(firstLine, lastLine);328 338 329 339 this._paintSelection(firstLine, lastLine); … … 339 349 } 340 350 341 var attributes = this._textModel.getAttributes(i, "highlight");351 var highlighterState = this._textModel.getAttribute(i, "highlighter-state"); 342 352 var plainTextStart = -1; 343 353 for (var j = 0; j < line.length;) { 344 var attribute = attributes &&attributes[j];354 var attribute = highlighterState && highlighterState.attributes[j]; 345 355 if (!attribute || !attribute.style) { 346 356 if (plainTextStart === -1) … … 631 641 }, 632 642 633 _invalidateHighlight: function(startLine)634 {635 if (!this._highlightingEnabled)636 return;637 var firstVisibleLine = Math.max(0, this._offsetToLineNumber(this._scrollTop) - 1);638 var lastVisibleLine = Math.min(this._textModel.linesCount, this._offsetToLineNumber(this._scrollTop + this._canvas.height) + 1);639 640 var damage = this._highlighter.highlight(startLine, lastVisibleLine);641 for (var line in damage)642 this._invalidateLines(line, parseInt(line) + 1);643 },644 645 643 _paintSelection: function(firstLine, lastLine) 646 644 { -
trunk/WebCore/inspector/front-end/TextEditorHighlighter.js
r52985 r53184 30 30 */ 31 31 32 WebInspector.TextEditorHighlighter = function(textModel )32 WebInspector.TextEditorHighlighter = function(textModel, damageCallback) 33 33 { 34 34 this._textModel = textModel; … … 41 41 this._styles["keyword"] = "rgb(170, 13, 145)"; 42 42 this._styles["number"] = "rgb(28, 0, 207)"; 43 44 this._damageCallback = damageCallback; 43 45 } 44 46 45 47 WebInspector.TextEditorHighlighter.prototype = { 46 highlight: function( startLine,endLine)48 highlight: function(endLine) 47 49 { 48 // Rewind to the last highlighted line to gain proper highlighter context. 49 while (startLine > 0 && !this._textModel.getAttribute(startLine - 1, 0, "highlighter-state")) 50 // First check if we have work to do. 51 var state = this._textModel.getAttribute(endLine - 1, "highlighter-state") 52 if (state && !state.outOfDate) { 53 // Last line is highlighted, just exit. 54 return; 55 } 56 57 this._requestedEndLine = endLine; 58 59 if (this._highlightTimer) { 60 // There is a timer scheduled, it will catch the new job based on the new endLine set. 61 return; 62 } 63 64 // We will be highlighting. First rewind to the last highlighted line to gain proper highlighter context. 65 var startLine = endLine; 66 while (startLine > 0) { 67 var state = this._textModel.getAttribute(startLine - 1, "highlighter-state"); 68 if (state && !state.outOfDate) 69 break; 50 70 startLine--; 71 } 51 72 73 // Do small highlight synchronously. This will provide instant highlight on PageUp / PageDown, gentle scrolling. 74 var toLine = Math.min(startLine + 200, endLine); 75 this._highlightLines(startLine, toLine); 76 77 // Schedule tail highlight if necessary. 78 if (endLine > toLine) 79 this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, endLine), 100); 80 }, 81 82 _highlightInChunks: function(startLine, endLine) 83 { 84 delete this._highlightTimer; 85 86 // First we always check if we have work to do. Could be that user scrolled back and we can quit. 87 var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlighter-state"); 88 if (state && !state.outOfDate) 89 return; 90 91 if (this._requestedEndLine !== endLine) { 92 // User keeps updating the job in between of our timer ticks. Just reschedule self, don't eat CPU (they must be scrolling). 93 this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 200); 94 return; 95 } 96 97 // Highlight 500 lines chunk. 98 var toLine = Math.min(startLine + 500, this._requestedEndLine); 99 this._highlightLines(startLine, toLine); 100 101 // Schedule tail highlight if necessary. 102 if (toLine < this._requestedEndLine) 103 this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, this._requestedEndLine), 10); 104 }, 105 106 updateHighlight: function(startLine, endLine) 107 { 108 // Start line was edited, we should highlight everything until endLine synchronously. 109 var state = this._textModel.getAttribute(startLine, "highlighter-state"); 110 if (!state || state.outOfDate) { 111 // Highlighter did not reach this point yet, nothing to update. It will reach it on subsequent timer tick and do the job. 112 return; 113 } 114 115 var restored = this._highlightLines(startLine, endLine); 116 117 // Set invalidated flag to the subsequent lines. 118 for (var i = endLine; i < this._textModel.linesCount; ++i) { 119 var highlighterState = this._textModel.getAttribute(i, "highlighter-state"); 120 if (highlighterState) 121 highlighterState.outOfDate = !restored; 122 else 123 return; 124 } 125 }, 126 127 _highlightLines: function(startLine, endLine) 128 { 52 129 // Restore highlighter context taken from previous line. 53 var state = this._textModel.getAttribute(startLine - 1, 0,"highlighter-state");54 55 56 57 58 // Each line has associated state attribute with pre- and post-highlighter conditions. 59 // Highlight lines from range until we find line precondition matching highlighter state.60 var damage = {};130 var state = this._textModel.getAttribute(startLine - 1, "highlighter-state"); 131 if (state) 132 this._tokenizer.condition = state.postCondition; 133 else 134 this._tokenizer.condition = this._tokenizer.initialCondition; 135 136 var damagedFrom = startLine; 137 var damagedTo = startLine; 61 138 for (var i = startLine; i < endLine; ++i) { 62 state = this._textModel.getAttribute(i, 0, "highlighter-state"); 63 if (state && state.preCondition === this._tokenizer.condition) { 64 // Following lines are up to date, no need re-highlight. 65 this._tokenizer.condition = state.postCondition; 66 continue; 67 } 68 69 damage[i] = true; 139 damagedTo = i; 70 140 71 141 state = {}; 72 142 state.preCondition = this._tokenizer.condition; 143 state.attributes = {}; 73 144 74 this._textModel.removeAttributes(i, "highlight"); 75 this._lex(this._textModel.line(i), i); 145 this._lex(this._textModel.line(i), i, state.attributes); 76 146 77 147 state.postCondition = this._tokenizer.condition; 78 this._textModel.addAttribute(i, 0, "highlighter-state", state); 148 this._textModel.setAttribute(i, "highlighter-state", state); 149 150 var nextLineState = this._textModel.getAttribute(i + 1, "highlighter-state"); 151 if (nextLineState && nextLineState.preCondition === state.postCondition) { 152 // Following lines are up to date, no need re-highlight. 153 this._damageCallback(damagedFrom, damagedTo); 154 return true; 155 } 79 156 } 80 81 state = this._textModel.getAttribute(endLine, 0, "highlighter-state"); 82 83 if (state && state.preCondition !== this._tokenizer.condition) { 84 // Requested highlight range is over, but we did not recover. Invalidate tail highlighting. 85 for (var i = endLine; i < this._textModel.linesCount; ++i) 86 this._textModel.removeAttributes(i, "highlighter-state"); 87 } 88 return damage; 157 this._damageCallback(damagedFrom, damagedTo); 158 return false; 89 159 }, 90 160 91 _lex: function(line, lineNumber ) {161 _lex: function(line, lineNumber, attributes) { 92 162 this._tokenizer.line = line; 93 163 var column = 0; … … 96 166 var tokenType = this._tokenizer.tokenType; 97 167 if (tokenType) 98 this._textModel.addAttribute(lineNumber, column, "highlight", { length: newColumn - column, style: this._styles[tokenType] });168 attributes[column] = { length: newColumn - column, style: this._styles[tokenType] }; 99 169 column = newColumn; 100 170 } while (column < line.length) -
trunk/WebCore/inspector/front-end/TextEditorModel.js
r52945 r53184 137 137 { 138 138 this._lines[lineNumber] = text; 139 delete this._attributes[lineNumber];140 139 }, 141 140 … … 187 186 }, 188 187 189 addAttribute: function(line, column, name, value)188 setAttribute: function(line, name, value) 190 189 { 191 190 var attrs = this._attributes[line]; … … 194 193 this._attributes[line] = attrs; 195 194 } 196 var family = attrs[name]; 197 if (!family) { 198 family = []; 199 attrs[name] = family; 200 } 201 family[column] = value; 202 }, 203 204 getAttribute: function(line, column, name) 205 { 206 var family = this.getAttributes(line, name); 207 return family ? family[column] : null; 208 }, 209 210 getAttributes: function(line, name) 195 attrs[name] = value; 196 }, 197 198 getAttribute: function(line, name) 211 199 { 212 200 var attrs = this._attributes[line]; … … 214 202 }, 215 203 216 removeAttribute s: function(line, name)204 removeAttribute: function(line, name) 217 205 { 218 206 var attrs = this._attributes[line];
Note: See TracChangeset
for help on using the changeset viewer.