提交 2ebf0e76 编写于 作者: A Alex Dima

Extract `renderLine` to its own file in /common/

上级 acda79ae
......@@ -6,10 +6,10 @@
import {TPromise} from 'vs/base/common/winjs.base';
import Schedulers = require('vs/base/common/async');
import ViewLine = require('vs/editor/browser/viewParts/lines/viewLine');
import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import {IModeService} from 'vs/editor/common/services/modeService';
import {IRenderLineOutput, renderLine} from 'vs/editor/common/viewLayout/viewLineRenderer';
export interface IColorizerOptions {
tabSize?: number;
......@@ -90,7 +90,7 @@ export function colorize(modeService:IModeService, text:string, mimeType:string,
}
export function colorizeLine(line:string, tokens:EditorCommon.ILineToken[], tabSize:number = 4): string {
var renderResult = ViewLine.renderLine({
var renderResult = renderLine({
lineContent: line,
parts: tokens,
stopRenderingLineAfter: -1,
......@@ -120,7 +120,7 @@ function actualColorize(lines:string[], mode:Modes.IMode, tabSize:number): IActu
length:number,
line: string,
tokenizeResult: Modes.ILineTokens,
renderResult: ViewLine.IRenderLineOutput,
renderResult: IRenderLineOutput,
retokenize: TPromise<void>[] = [];
for (i = 0, length = lines.length; i < length; i++) {
......@@ -131,7 +131,7 @@ function actualColorize(lines:string[], mode:Modes.IMode, tabSize:number): IActu
retokenize.push(tokenizeResult.retokenize);
}
renderResult = ViewLine.renderLine({
renderResult = renderLine({
lineContent: line,
parts: tokenizeResult.tokens,
stopRenderingLineAfter: -1,
......
......@@ -9,7 +9,8 @@ import {StyleMutator} from 'vs/base/browser/dom';
import {IVisibleLineData} from 'vs/editor/browser/view/viewLayer';
import {ILineParts, createLineParts} from 'vs/editor/common/viewLayout/viewLineParts';
import {ClassNames, IViewContext, HorizontalRange} from 'vs/editor/browser/editorBrowser';
import {IModelDecoration, IConfigurationChangedEvent, ILineToken} from 'vs/editor/common/editorCommon';
import {IModelDecoration, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon';
import {renderLine} from 'vs/editor/common/viewLayout/viewLineRenderer';
export class ViewLine implements IVisibleLineData {
......@@ -516,160 +517,3 @@ function createNormalLine(context: IViewContext): ViewLine {
return new ViewLine(context);
}
export interface IRenderLineInput {
lineContent: string;
tabSize: number;
stopRenderingLineAfter: number;
renderWhitespace: boolean;
parts: ILineToken[];
}
export interface IRenderLineOutput {
charOffsetInPart: number[];
lastRenderedPartIndex: number;
output: string[];
}
let _space = ' '.charCodeAt(0);
let _tab = '\t'.charCodeAt(0);
let _lowerThan = '<'.charCodeAt(0);
let _greaterThan = '>'.charCodeAt(0);
let _ampersand = '&'.charCodeAt(0);
let _carriageReturn = '\r'.charCodeAt(0);
let _lineSeparator = '\u2028'.charCodeAt(0); //http://www.fileformat.info/info/unicode/char/2028/index.htm
let _bom = 65279;
let _replacementCharacter = '\ufffd';
export function renderLine(input:IRenderLineInput): IRenderLineOutput {
const lineText = input.lineContent;
let lineTextLength = lineText.length;
const stopRenderingLineAfter = input.stopRenderingLineAfter;
const tabSize = input.tabSize;
if (lineTextLength === 0) {
return {
charOffsetInPart: [],
lastRenderedPartIndex: 0,
// This is basically for IE's hit test to work
output: ['<span><span>&nbsp;</span></span>']
};
}
let result: IRenderLineOutput = {
charOffsetInPart: [],
lastRenderedPartIndex: 0,
output: []
};
result.output.push('<span>');
let partClassName: string,
partIndex = -1,
nextPartIndex = 0,
tabsCharDelta = 0,
charOffsetInPart = 0,
append = '',
renderWhitespace = false;
let actualLineParts = input.parts;
if (actualLineParts.length === 0) {
throw new Error('Cannot render non empty line without line parts!');
}
if (stopRenderingLineAfter !== -1 && lineTextLength > stopRenderingLineAfter - 1) {
append = lineText.substr(stopRenderingLineAfter - 1, 1);
lineTextLength = stopRenderingLineAfter - 1;
}
for (let i = 0; i < lineTextLength; i++) {
if (i === nextPartIndex) {
partIndex++;
nextPartIndex = (partIndex + 1 < actualLineParts.length ? actualLineParts[partIndex + 1].startIndex : Number.MAX_VALUE);
if (i > 0) {
result.output.push('</span>');
}
result.output.push('<span class="');
partClassName = 'token ' + actualLineParts[partIndex].type.replace(/[^a-z0-9\-]/gi, ' ');
if (input.renderWhitespace) {
renderWhitespace = partClassName.indexOf('whitespace') >= 0;
}
result.output.push(partClassName);
result.output.push('">');
charOffsetInPart = 0;
}
result.charOffsetInPart[i] = charOffsetInPart;
let charCode = lineText.charCodeAt(i);
switch (charCode) {
case _tab:
let insertSpacesCount = tabSize - (i + tabsCharDelta) % tabSize;
tabsCharDelta += insertSpacesCount - 1;
charOffsetInPart += insertSpacesCount - 1;
if (insertSpacesCount > 0) {
result.output.push(renderWhitespace ? '&rarr;' : '&nbsp;');
insertSpacesCount--;
}
while (insertSpacesCount > 0) {
result.output.push('&nbsp;');
insertSpacesCount--;
}
break;
case _space:
result.output.push(renderWhitespace ? '&middot;' : '&nbsp;');
break;
case _lowerThan:
result.output.push('&lt;');
break;
case _greaterThan:
result.output.push('&gt;');
break;
case _ampersand:
result.output.push('&amp;');
break;
case 0:
result.output.push('&#00;');
break;
case _bom:
case _lineSeparator:
result.output.push(_replacementCharacter);
break;
case _carriageReturn:
// zero width space, because carriage return would introduce a line break
result.output.push('&#8203');
break;
default:
result.output.push(lineText.charAt(i));
}
charOffsetInPart ++;
}
result.output.push('</span>');
// When getting client rects for the last character, we will position the
// text range at the end of the span, insteaf of at the beginning of next span
result.charOffsetInPart[lineTextLength] = charOffsetInPart;
// In case we stop rendering, we record here the index of the last span
// that should be used for getting client rects
result.lastRenderedPartIndex = partIndex;
if (append.length > 0) {
result.output.push('<span class="');
result.output.push(partClassName);
result.output.push('" style="color:grey">');
result.output.push(append);
result.output.push('&hellip;</span>');
}
result.output.push('</span>');
return result;
}
......@@ -16,11 +16,11 @@ import EditorCommon = require('vs/editor/common/editorCommon');
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import Actions = require('vs/base/common/actions');
import Sash = require('vs/base/browser/ui/sash/sash');
import ViewLine = require('vs/editor/browser/viewParts/lines/viewLine');
import ViewLineParts = require('vs/editor/common/viewLayout/viewLineParts');
import Schedulers = require('vs/base/common/async');
import {Range} from 'vs/editor/common/core/range';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
import {renderLine} from 'vs/editor/common/viewLayout/viewLineRenderer';
interface IEditorScrollEvent {
scrollLeft: number;
......@@ -1772,7 +1772,7 @@ class InlineViewZonesComputer extends ViewZonesComputer {
parts = ViewLineParts.createLineParts(lineNumber, lineContent, lineTokens, decorations, config.renderWhitespace);
var r = ViewLine.renderLine({
var r = renderLine({
lineContent: lineContent,
tabSize: indentation.tabSize,
stopRenderingLineAfter: config.stopRenderingLineAfter,
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {ILineToken} from 'vs/editor/common/editorCommon';
export interface IRenderLineInput {
lineContent: string;
tabSize: number;
stopRenderingLineAfter: number;
renderWhitespace: boolean;
parts: ILineToken[];
}
export interface IRenderLineOutput {
charOffsetInPart: number[];
lastRenderedPartIndex: number;
output: string[];
}
let _space = ' '.charCodeAt(0);
let _tab = '\t'.charCodeAt(0);
let _lowerThan = '<'.charCodeAt(0);
let _greaterThan = '>'.charCodeAt(0);
let _ampersand = '&'.charCodeAt(0);
let _carriageReturn = '\r'.charCodeAt(0);
let _lineSeparator = '\u2028'.charCodeAt(0); //http://www.fileformat.info/info/unicode/char/2028/index.htm
let _bom = 65279;
let _replacementCharacter = '\ufffd';
export function renderLine(input:IRenderLineInput): IRenderLineOutput {
const lineText = input.lineContent;
let lineTextLength = lineText.length;
const stopRenderingLineAfter = input.stopRenderingLineAfter;
const tabSize = input.tabSize;
if (lineTextLength === 0) {
return {
charOffsetInPart: [],
lastRenderedPartIndex: 0,
// This is basically for IE's hit test to work
output: ['<span><span>&nbsp;</span></span>']
};
}
let result: IRenderLineOutput = {
charOffsetInPart: [],
lastRenderedPartIndex: 0,
output: []
};
result.output.push('<span>');
let partClassName: string,
partIndex = -1,
nextPartIndex = 0,
tabsCharDelta = 0,
charOffsetInPart = 0,
append = '',
renderWhitespace = false;
let actualLineParts = input.parts;
if (actualLineParts.length === 0) {
throw new Error('Cannot render non empty line without line parts!');
}
if (stopRenderingLineAfter !== -1 && lineTextLength > stopRenderingLineAfter - 1) {
append = lineText.substr(stopRenderingLineAfter - 1, 1);
lineTextLength = stopRenderingLineAfter - 1;
}
for (let i = 0; i < lineTextLength; i++) {
if (i === nextPartIndex) {
partIndex++;
nextPartIndex = (partIndex + 1 < actualLineParts.length ? actualLineParts[partIndex + 1].startIndex : Number.MAX_VALUE);
if (i > 0) {
result.output.push('</span>');
}
result.output.push('<span class="');
partClassName = 'token ' + actualLineParts[partIndex].type.replace(/[^a-z0-9\-]/gi, ' ');
if (input.renderWhitespace) {
renderWhitespace = partClassName.indexOf('whitespace') >= 0;
}
result.output.push(partClassName);
result.output.push('">');
charOffsetInPart = 0;
}
result.charOffsetInPart[i] = charOffsetInPart;
let charCode = lineText.charCodeAt(i);
switch (charCode) {
case _tab:
let insertSpacesCount = tabSize - (i + tabsCharDelta) % tabSize;
tabsCharDelta += insertSpacesCount - 1;
charOffsetInPart += insertSpacesCount - 1;
if (insertSpacesCount > 0) {
result.output.push(renderWhitespace ? '&rarr;' : '&nbsp;');
insertSpacesCount--;
}
while (insertSpacesCount > 0) {
result.output.push('&nbsp;');
insertSpacesCount--;
}
break;
case _space:
result.output.push(renderWhitespace ? '&middot;' : '&nbsp;');
break;
case _lowerThan:
result.output.push('&lt;');
break;
case _greaterThan:
result.output.push('&gt;');
break;
case _ampersand:
result.output.push('&amp;');
break;
case 0:
result.output.push('&#00;');
break;
case _bom:
case _lineSeparator:
result.output.push(_replacementCharacter);
break;
case _carriageReturn:
// zero width space, because carriage return would introduce a line break
result.output.push('&#8203');
break;
default:
result.output.push(lineText.charAt(i));
}
charOffsetInPart ++;
}
result.output.push('</span>');
// When getting client rects for the last character, we will position the
// text range at the end of the span, insteaf of at the beginning of next span
result.charOffsetInPart[lineTextLength] = charOffsetInPart;
// In case we stop rendering, we record here the index of the last span
// that should be used for getting client rects
result.lastRenderedPartIndex = partIndex;
if (append.length > 0) {
result.output.push('<span class="');
result.output.push(partClassName);
result.output.push('" style="color:grey">');
result.output.push(append);
result.output.push('&hellip;</span>');
}
result.output.push('</span>');
return result;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册