summaryrefslogtreecommitdiffstats
path: root/WebCore/inspector/front-end/TextEditorHighlighter.js
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /WebCore/inspector/front-end/TextEditorHighlighter.js
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebCore/inspector/front-end/TextEditorHighlighter.js')
-rw-r--r--WebCore/inspector/front-end/TextEditorHighlighter.js137
1 files changed, 50 insertions, 87 deletions
diff --git a/WebCore/inspector/front-end/TextEditorHighlighter.js b/WebCore/inspector/front-end/TextEditorHighlighter.js
index cf0b590..4ac831e 100644
--- a/WebCore/inspector/front-end/TextEditorHighlighter.js
+++ b/WebCore/inspector/front-end/TextEditorHighlighter.js
@@ -34,24 +34,31 @@ WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
this._textModel = textModel;
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
this._damageCallback = damageCallback;
+ this.reset();
}
WebInspector.TextEditorHighlighter.prototype = {
set mimeType(mimeType)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
- if (tokenizer)
+ if (tokenizer) {
this._tokenizer = tokenizer;
+ this._tokenizerCondition = this._tokenizer.initialCondition;
+ }
+ },
+
+ reset: function()
+ {
+ this._lastHighlightedLine = 0;
+ this._lastHighlightedColumn = 0;
+ this._tokenizerCondition = this._tokenizer.initialCondition;
},
highlight: function(endLine)
{
// 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.
+ if (endLine <= this._lastHighlightedLine)
return;
- }
this._requestedEndLine = endLine;
@@ -60,110 +67,66 @@ WebInspector.TextEditorHighlighter.prototype = {
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._highlightInChunks(startLine, toLine);
+ this._highlightInChunks(endLine);
// Schedule tail highlight if necessary.
- if (endLine > toLine)
- this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, endLine), 100);
+ if (this._lastHighlightedLine < endLine)
+ this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, endLine), 100);
},
- _highlightInChunks: function(startLine, endLine)
+ _highlightInChunks: function(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)
+ if (this._requestedEndLine <= this._lastHighlightedLine)
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), 100);
+ this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 100);
return;
}
- // Highlight 500 lines chunk.
- var toLine = Math.min(startLine + 500, this._requestedEndLine);
- this._highlightLines(startLine, toLine);
+ this._highlightLines(this._requestedEndLine);
// Schedule tail highlight if necessary.
- if (toLine < this._requestedEndLine)
- this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, toLine, this._requestedEndLine), 10);
+ if (this._lastHighlightedLine < this._requestedEndLine)
+ this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._requestedEndLine), 10);
},
- updateHighlight: function(startLine, endLine)
+ _highlightLines: function(endLine)
{
- // Start line was edited, we should highlight everything until endLine synchronously.
- if (startLine) {
- var state = this._textModel.getAttribute(startLine - 1, "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, "highlighter-state");
- if (state)
- this._tokenizer.condition = state.postCondition;
- else
- this._tokenizer.condition = this._tokenizer.initialCondition;
-
- for (var i = startLine; i < endLine; ++i) {
- state = {};
- state.preCondition = this._tokenizer.condition;
- state.attributes = {};
-
- this._lex(this._textModel.line(i), i, state.attributes);
-
- state.postCondition = this._tokenizer.condition;
- this._textModel.setAttribute(i, "highlighter-state", state);
-
- var nextLineState = this._textModel.getAttribute(i + 1, "highlighter-state");
- if (nextLineState && this._tokenizer.hasCondition(nextLineState.preCondition)) {
- // Following lines are up to date, no need re-highlight.
- this._damageCallback(startLine, i + 1);
- return true;
- }
+ // Tokenizer is stateless and reused accross viewers, restore its condition before highlight and save it after.
+ this._tokenizer.condition = this._tokenizerCondition;
+ var tokensCount = 0;
+ for (var lineNumber = this._lastHighlightedLine; lineNumber < endLine; ++lineNumber) {
+ var line = this._textModel.line(lineNumber);
+ this._tokenizer.line = line;
+ var attributes = this._textModel.getAttribute(lineNumber, "highlight") || {};
+
+ // Highlight line.
+ do {
+ var newColumn = this._tokenizer.nextToken(this._lastHighlightedColumn);
+ var tokenType = this._tokenizer.tokenType;
+ if (tokenType)
+ attributes[this._lastHighlightedColumn] = { length: newColumn - this._lastHighlightedColumn, tokenType: tokenType, subTokenizer: this._tokenizer.subTokenizer };
+ this._lastHighlightedColumn = newColumn;
+ if (++tokensCount > 1000)
+ break;
+ } while (this._lastHighlightedColumn < line.length)
+
+ this._textModel.setAttribute(lineNumber, "highlight", attributes);
+ if (this._lastHighlightedColumn < line.length) {
+ // Too much work for single chunk - exit.
+ break;
+ } else
+ this._lastHighlightedColumn = 0;
}
- this._damageCallback(startLine, endLine);
- return false;
- },
- _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)
- attributes[column] = { length: newColumn - column, tokenType: tokenType };
- column = newColumn;
- } while (column < line.length)
+ this._damageCallback(this._lastHighlightedLine, lineNumber);
+ this._tokenizerCondition = this._tokenizer.condition;
+ this._lastHighlightedLine = lineNumber;
}
}