Chromium Code Reviews| Index: third_party/WebKit/Source/devtools/front_end/changes/ChangesHighlighter.js |
| diff --git a/third_party/WebKit/Source/devtools/front_end/changes/ChangesHighlighter.js b/third_party/WebKit/Source/devtools/front_end/changes/ChangesHighlighter.js |
| index 4a7a0415f3f39e74977a2cc3bde9e332a1aed5ad..e071a930a51795b064260cfeb7fee6ff7516ee49 100644 |
| --- a/third_party/WebKit/Source/devtools/front_end/changes/ChangesHighlighter.js |
| +++ b/third_party/WebKit/Source/devtools/front_end/changes/ChangesHighlighter.js |
| @@ -4,22 +4,73 @@ |
| /** |
| * @param {!Object} config |
| - * @param {{rows: !Array<!Changes.ChangesView.Row>}} parserConfig |
| + * @param {{rows: !Array<!Changes.ChangesView.Row>, baselineLines: !Array<string>, currentLines: !Array<string>, mimeType: string}} parserConfig |
| * @return {{ |
| * startState: function():!Changes.ChangesHighlighter.DiffState, |
| * token: function({next: function()}, !Changes.ChangesHighlighter.DiffState):string, |
| * blankLine: function(!Changes.ChangesHighlighter.DiffState):string, |
| + * copyState: function(!Changes.ChangesHighlighter.DiffState):Changes.ChangesHighlighter.DiffState |
| * }} |
| */ |
| Changes.ChangesHighlighter = function(config, parserConfig) { |
| var rows = parserConfig.rows; |
| + var baselineLines = parserConfig.baselineLines; |
| + var currentLines = parserConfig.currentLines; |
| + var syntaxHighlightMode = CodeMirror.getMode({}, parserConfig.mimeType); |
| + |
| + /** |
| + * @param {!Changes.ChangesHighlighter.DiffState} state |
| + * @param {number} baselineLineNumber |
| + * @param {number} currentLineNumber |
| + */ |
| + function fastForward(state, baselineLineNumber, currentLineNumber) { |
| + if (baselineLineNumber > state.baselineLineNumber) { |
| + fastForwardSyntaxHighlighter(state.baselineSyntaxState, state.baselineLineNumber, baselineLineNumber, baselineLines); |
| + state.baselineLineNumber = baselineLineNumber; |
| + } |
| + if (currentLineNumber > state.currentLineNumber) { |
| + fastForwardSyntaxHighlighter(state.currentSyntaxState, state.currentLineNumber, currentLineNumber, currentLines); |
| + state.currentLineNumber = currentLineNumber; |
| + } |
| + } |
| + |
| + /** |
| + * @param {!Object} syntaxState |
| + * @param {number} from |
| + * @param {number} to |
| + * @param {!Array<string>} lines |
| + */ |
| + function fastForwardSyntaxHighlighter(syntaxState, from, to, lines) { |
| + var lineNumber = from; |
| + while (lineNumber < to && lineNumber < lines.length) { |
| + var stream = new CodeMirror.StringStream(lines[lineNumber]); |
| + if (stream.eol() && syntaxHighlightMode.blankLine) |
| + syntaxHighlightMode.blankLine(syntaxState); |
| + while (!stream.eol()) { |
| + syntaxHighlightMode.token(stream, syntaxState); |
| + stream.start = stream.pos; |
| + } |
| + lineNumber++; |
| + } |
| + } |
| return { |
| /** |
| * @return {!Changes.ChangesHighlighter.DiffState} |
| */ |
| startState: function() { |
| - return {lineNumber: 0, index: 0}; |
| + return { |
| + lineNumber: 0, |
|
lushnikov
2017/04/03 23:11:19
rowNumber
einbinder
2017/04/04 22:21:53
Done.
|
| + diffTokenIndex: 0, |
| + currentLineNumber: 0, |
| + baselineLineNumber: 0, |
| + currentSyntaxState: CodeMirror.startState(syntaxHighlightMode), |
| + baselineSyntaxState: CodeMirror.startState(syntaxHighlightMode), |
| + syntaxPosition: 0, |
| + diffPosition: 0, |
| + syntaxStyle: '', |
| + diffStyle: '' |
| + }; |
| }, |
| /** |
| @@ -33,15 +84,42 @@ Changes.ChangesHighlighter = function(config, parserConfig) { |
| stream.next(); |
| return ''; |
| } |
| + fastForward(state, row.baselineLineNumber - 1, row.currentLineNumber - 1); |
| var classes = ''; |
| - if (state.index === 0) |
| + if (stream.pos === 0) |
| classes += ' line-background-' + row.type + ' line-' + row.type; |
| - stream.pos += row.content[state.index].text.length; |
| - classes += ' ' + row.content[state.index].className; |
| - state.index++; |
| - if (state.index >= row.content.length) { |
| + |
| + if (state.diffPosition <= state.syntaxPosition) { |
| + state.diffPosition += row.content[state.diffTokenIndex].text.length; |
|
lushnikov
2017/04/03 23:11:19
row.tokens
einbinder
2017/04/04 22:21:53
Done.
|
| + state.diffStyle = row.content[state.diffTokenIndex].className; |
| + state.diffTokenIndex++; |
| + } |
| + |
| + if (state.diffPosition >= state.syntaxPosition) { |
|
lushnikov
2017/04/03 23:11:19
this starts to depend on execution of previous if-
einbinder
2017/04/04 22:21:53
Done.
|
| + if (row.type === Changes.ChangesView.RowType.Deletion || row.type === Changes.ChangesView.RowType.Addition || |
| + row.type === Changes.ChangesView.RowType.Equal) { |
| + state.syntaxStyle = syntaxHighlightMode.token( |
| + stream, row.type === Changes.ChangesView.RowType.Deletion ? state.baselineSyntaxState : state.currentSyntaxState); |
| + state.syntaxPosition = stream.pos; |
| + } else { |
| + state.syntaxStyle = ''; |
| + state.syntaxPosition = state.diffPosition; |
| + } |
| + } |
| + |
| + stream.pos = Math.min(state.syntaxPosition, state.diffPosition); |
| + classes += ' ' + state.syntaxStyle; |
| + classes += ' ' + state.diffStyle; |
| + |
| + if (stream.eol()) { |
| state.lineNumber++; |
| - state.index = 0; |
| + if (row.type === Changes.ChangesView.RowType.Deletion) |
| + state.baselineLineNumber++; |
| + else |
| + state.currentLineNumber++; |
| + state.diffPosition = 0; |
| + state.syntaxPosition = 0; |
| + state.diffTokenIndex = 0; |
| } |
| return classes; |
| }, |
| @@ -53,15 +131,52 @@ Changes.ChangesHighlighter = function(config, parserConfig) { |
| blankLine: function(state) { |
| var row = rows[state.lineNumber]; |
| state.lineNumber++; |
| - state.index = 0; |
| + state.syntaxPosition = 0; |
| + state.diffPosition = 0; |
| + state.diffTokenIndex = 0; |
| if (!row) |
| return ''; |
| - return 'line-background-' + row.type + ' line-' + row.type; |
| + if (row.type === Changes.ChangesView.RowType.Deletion) |
|
lushnikov
2017/04/03 23:11:19
it's unclear why this and the following are non-sy
einbinder
2017/04/04 22:21:53
Done.
|
| + state.baselineLineNumber++; |
| + else if (row.type === Changes.ChangesView.RowType.Equal || row.type === Changes.ChangesView.RowType.Addition) |
| + state.currentLineNumber++; |
| + var style = ''; |
| + if (syntaxHighlightMode.blankLine) { |
| + style = syntaxHighlightMode.blankLine( |
| + row.type === Changes.ChangesView.RowType.Deletion ? state.baselineSyntaxState : state.currentSyntaxState); |
|
lushnikov
2017/04/03 23:11:19
row => diffRow to be coherent with ChangesView
einbinder
2017/04/04 22:21:53
Done.
|
| + } |
| + return style + ' line-background-' + row.type + ' line-' + row.type; |
| + }, |
| + |
| + /** |
| + * @param {!Changes.ChangesHighlighter.DiffState} state |
| + * @return {!Changes.ChangesHighlighter.DiffState} |
| + */ |
| + copyState: function(state) { |
| + var newState = /** @type {!Changes.ChangesHighlighter.DiffState} */ ({}); |
| + for (var i in state) |
|
lushnikov
2017/04/03 23:11:19
Object.assign?!
einbinder
2017/04/04 22:21:53
Done.
|
| + newState[i] = state[i]; |
| + newState.currentSyntaxState = CodeMirror.copyState(syntaxHighlightMode, state.currentSyntaxState); |
| + newState.baselineSyntaxState = CodeMirror.copyState(syntaxHighlightMode, state.baselineSyntaxState); |
| + return newState; |
| } |
| }; |
| }; |
| -/** @typedef {!{lineNumber: number, index: number}} */ |
| +/** |
| + * @typedef {!{ |
| + * lineNumber: number, |
| + * diffTokenIndex: number, |
| + * currentLineNumber: number, |
| + * baselineLineNumber: number, |
| + * currentSyntaxState: !Object, |
| + * baselineSyntaxState: !Object, |
| + * syntaxPosition: number, |
| + * diffPosition: number, |
| + * syntaxStyle: string, |
| + * diffStyle: string |
| + * }} |
| + */ |
| Changes.ChangesHighlighter.DiffState; |
| CodeMirror.defineMode('devtools-diff', Changes.ChangesHighlighter); |