fix BCE
This commit is contained in:
+17
-1
@@ -228,6 +228,7 @@ if (document.location.pathname === '/test') {
|
||||
document.getElementById('add-decoration').addEventListener('click', addDecoration);
|
||||
document.getElementById('add-overview-ruler').addEventListener('click', addOverviewRuler);
|
||||
document.getElementById('weblinks-test').addEventListener('click', testWeblinks);
|
||||
document.getElementById('bce').addEventListener('click', coloredErase);
|
||||
addVtButtons();
|
||||
}
|
||||
|
||||
@@ -1186,6 +1187,21 @@ ipv6 https://[::1]/with/some?vars=and&a#hash aaa
|
||||
stop at final '.': This is a sentence with an url to http://example.com.
|
||||
stop at final '?': Is this the right url http://example.com/?
|
||||
stop at final '?': Maybe this one http://example.com/with?arguments=false?
|
||||
`;
|
||||
`;
|
||||
term.write(linkExamples.split('\n').join('\r\n'));
|
||||
}
|
||||
|
||||
|
||||
function coloredErase(): void {
|
||||
const data = `
|
||||
Test BG-colored Erase (BCE):
|
||||
The color block in the following lines should look identical.
|
||||
For newly created rows at the bottom the last color should be applied
|
||||
for all cells to the right.
|
||||
|
||||
def 41 42 43 44 45 46 47\x1b[47m
|
||||
\x1b[m \x1b[41m \x1b[42m \x1b[43m \x1b[44m \x1b[45m \x1b[46m \x1b[47m
|
||||
\x1b[m\x1b[5X\x1b[41m\x1b[5C\x1b[5X\x1b[42m\x1b[5C\x1b[5X\x1b[43m\x1b[5C\x1b[5X\x1b[44m\x1b[5C\x1b[5X\x1b[45m\x1b[5C\x1b[5X\x1b[46m\x1b[5C\x1b[5X\x1b[47m\x1b[5C\x1b[5X\x1b[m
|
||||
`;
|
||||
term.write(data.split('\n').join('\r\n'));
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
<dd><button id="sgr-test" title="Write text with SGR attribute">SGR test</button></dd>
|
||||
<dd><button id="ansi-colors" title="Write a wide range of ansi colors">Ansi colors test</button></dd>
|
||||
<dd><button id="osc-hyperlinks" title="Write some OSC 8 hyperlinks">Ansi hyperlinks test</button></dd>
|
||||
<dd><button id="bce" title="Test colored erase">Colored Erase (BCE)</button></dd>
|
||||
|
||||
<dt>Decorations</dt>
|
||||
<dd><button id="add-decoration" title="Add a decoration to the terminal">Decoration</button></dd>
|
||||
|
||||
@@ -444,7 +444,6 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
cursorX,
|
||||
cursorBlink,
|
||||
this.dimensions.css.cell.width,
|
||||
this._bufferService.cols,
|
||||
this._fontMetrics,
|
||||
this._linkState
|
||||
)
|
||||
@@ -476,6 +475,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
|
||||
const cursorBlink = this._optionsService.rawOptions.cursorBlink;
|
||||
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
||||
cols = Math.min(cols, this._bufferService.cols);
|
||||
|
||||
// refresh rows within link range
|
||||
this._linkState[0] = +enabled;
|
||||
@@ -499,7 +499,6 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
cursorX,
|
||||
cursorBlink,
|
||||
this.dimensions.css.cell.width,
|
||||
this._bufferService.cols,
|
||||
this._fontMetrics,
|
||||
this._linkState
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('DomRendererRowFactory', () => {
|
||||
|
||||
describe('createRow', () => {
|
||||
it('should not create anything for an empty row', () => {
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
''
|
||||
);
|
||||
@@ -49,7 +49,7 @@ describe('DomRendererRowFactory', () => {
|
||||
lineData.setCell(0, CellData.fromCharData([DEFAULT_ATTR, '語', 2, '語'.charCodeAt(0)]));
|
||||
// There should be no element for the following "empty" cell
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, '', 0, 0]));
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span style="width: 10px;">語</span>'
|
||||
);
|
||||
@@ -57,7 +57,7 @@ describe('DomRendererRowFactory', () => {
|
||||
|
||||
it('should add class for cursor and cursor style', () => {
|
||||
for (const style of ['block', 'bar', 'underline']) {
|
||||
const fragment = rowFactory.createRow(lineData, 0, true, style, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, true, style, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
`<span class="xterm-cursor xterm-cursor-${style}"> </span>`
|
||||
);
|
||||
@@ -65,27 +65,18 @@ describe('DomRendererRowFactory', () => {
|
||||
});
|
||||
|
||||
it('should add class for cursor blink', () => {
|
||||
const fragment = rowFactory.createRow(lineData, 0, true, 'block', 0, true, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, true, 'block', 0, true, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
`<span class="xterm-cursor xterm-cursor-blink xterm-cursor-block"> </span>`
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render cells that go beyond the terminal\'s columns', () => {
|
||||
lineData.setCell(0, CellData.fromCharData([DEFAULT_ATTR, 'a', 1, 'a'.charCodeAt(0)]));
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, 'b', 1, 'b'.charCodeAt(0)]));
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 1, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span>a</span>'
|
||||
);
|
||||
});
|
||||
|
||||
describe('attributes', () => {
|
||||
it('should add class for bold', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.fg = DEFAULT_ATTR_DATA.fg | FgFlags.BOLD;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-bold">a</span>'
|
||||
);
|
||||
@@ -95,7 +86,7 @@ describe('DomRendererRowFactory', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.ITALIC;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-italic">a</span>'
|
||||
);
|
||||
@@ -105,7 +96,7 @@ describe('DomRendererRowFactory', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.DIM;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-dim">a</span>'
|
||||
);
|
||||
@@ -118,7 +109,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.HAS_EXTENDED;
|
||||
cell.extended.underlineStyle = UnderlineStyle.SINGLE;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-underline-1">a</span>'
|
||||
);
|
||||
@@ -129,7 +120,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.HAS_EXTENDED;
|
||||
cell.extended.underlineStyle = UnderlineStyle.DOUBLE;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-underline-2">a</span>'
|
||||
);
|
||||
@@ -140,7 +131,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.HAS_EXTENDED;
|
||||
cell.extended.underlineStyle = UnderlineStyle.CURLY;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-underline-3">a</span>'
|
||||
);
|
||||
@@ -151,7 +142,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.HAS_EXTENDED;
|
||||
cell.extended.underlineStyle = UnderlineStyle.DOTTED;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-underline-4">a</span>'
|
||||
);
|
||||
@@ -162,7 +153,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.HAS_EXTENDED;
|
||||
cell.extended.underlineStyle = UnderlineStyle.DASHED;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-underline-5">a</span>'
|
||||
);
|
||||
@@ -173,7 +164,7 @@ describe('DomRendererRowFactory', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.bg = DEFAULT_ATTR_DATA.bg | BgFlags.OVERLINE;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-overline">a</span>'
|
||||
);
|
||||
@@ -183,7 +174,7 @@ describe('DomRendererRowFactory', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.fg = DEFAULT_ATTR_DATA.fg | FgFlags.STRIKETHROUGH;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-strikethrough">a</span>'
|
||||
);
|
||||
@@ -196,7 +187,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg &= ~Attributes.PCOLOR_MASK;
|
||||
cell.fg |= i;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
`<span class="xterm-fg-${i}">a</span>`
|
||||
);
|
||||
@@ -210,7 +201,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.bg &= ~Attributes.PCOLOR_MASK;
|
||||
cell.bg |= i;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
`<span class="xterm-bg-${i}">a</span>`
|
||||
);
|
||||
@@ -222,7 +213,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg |= Attributes.CM_P16 | 2 | FgFlags.INVERSE;
|
||||
cell.bg |= Attributes.CM_P16 | 1;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-bg-2 xterm-fg-1">a</span>'
|
||||
);
|
||||
@@ -233,7 +224,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg |= FgFlags.INVERSE;
|
||||
cell.bg |= Attributes.CM_P16 | 1;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-bg-257 xterm-fg-1">a</span>'
|
||||
);
|
||||
@@ -243,7 +234,7 @@ describe('DomRendererRowFactory', () => {
|
||||
const cell = CellData.fromCharData([0, 'a', 1, 'a'.charCodeAt(0)]);
|
||||
cell.fg |= Attributes.CM_P16 | 1 | FgFlags.INVERSE;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-bg-1 xterm-fg-257">a</span>'
|
||||
);
|
||||
@@ -256,7 +247,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg &= ~Attributes.PCOLOR_MASK;
|
||||
cell.fg |= i;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
`<span class="xterm-bold xterm-fg-${i + 8}">a</span>`
|
||||
);
|
||||
@@ -268,7 +259,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg |= Attributes.CM_RGB | 1 << 16 | 2 << 8 | 3;
|
||||
cell.bg |= Attributes.CM_RGB | 4 << 16 | 5 << 8 | 6;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span style="background-color:#040506;color:#010203;">a</span>'
|
||||
);
|
||||
@@ -279,7 +270,7 @@ describe('DomRendererRowFactory', () => {
|
||||
cell.fg |= Attributes.CM_RGB | 1 << 16 | 2 << 8 | 3 | FgFlags.INVERSE;
|
||||
cell.bg |= Attributes.CM_RGB | 4 << 16 | 5 << 8 | 6;
|
||||
lineData.setCell(0, cell);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span style="background-color:#010203;color:#040506;">a</span>'
|
||||
);
|
||||
@@ -291,7 +282,7 @@ describe('DomRendererRowFactory', () => {
|
||||
lineData.setCell(0, CellData.fromCharData([DEFAULT_ATTR, 'a', 1, 'a'.charCodeAt(0)]));
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, 'b', 1, 'b'.charCodeAt(0)]));
|
||||
rowFactory.handleSelectionChanged([1, 0], [2, 0], false);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span>a</span><span class="xterm-decoration-top">b</span>'
|
||||
);
|
||||
@@ -299,7 +290,7 @@ describe('DomRendererRowFactory', () => {
|
||||
it('should force whitespace cells to be rendered above the background', () => {
|
||||
lineData.setCell(1, CellData.fromCharData([DEFAULT_ATTR, 'a', 1, 'a'.charCodeAt(0)]));
|
||||
rowFactory.handleSelectionChanged([0, 0], [2, 0], false);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, 20, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
const fragment = rowFactory.createRow(lineData, 0, false, undefined, 0, false, 5, EMPTY_METRICS, EMPTY_LINKSTATE);
|
||||
assert.equal(getFragmentHtml(fragment),
|
||||
'<span class="xterm-decoration-top"> </span><span class="xterm-decoration-top">a</span>'
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { IBufferLine, ICellData, IColor } from 'common/Types';
|
||||
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
|
||||
import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR, Attributes } from 'common/buffer/Constants';
|
||||
import { NULL_CELL_CODE, WHITESPACE_CELL_CHAR, Attributes, NULL_CELL_WIDTH } from 'common/buffer/Constants';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
||||
import { color, rgba } from 'common/Color';
|
||||
@@ -57,28 +57,19 @@ export class DomRendererRowFactory {
|
||||
cursorX: number,
|
||||
cursorBlink: boolean,
|
||||
cellWidth: number,
|
||||
cols: number,
|
||||
metrics: Uint8Array,
|
||||
linkState: Uint8Array
|
||||
): DocumentFragment {
|
||||
|
||||
const fragment = this._document.createDocumentFragment();
|
||||
|
||||
const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
|
||||
// Find the line length first, this prevents the need to output a bunch of
|
||||
// empty cells at the end. This cannot easily be integrated into the main
|
||||
// loop below because of the colCount feature (which can be removed after we
|
||||
// properly support reflow and disallow data to go beyond the right-side of
|
||||
// the viewport).
|
||||
let lineLength = 0;
|
||||
for (let x = Math.min(lineData.length, cols) - 1; x >= 0; x--) {
|
||||
if (lineData.loadCell(x, this._workCell).getCode() !== NULL_CELL_CODE || (isCursorRow && x === cursorX)) {
|
||||
lineLength = x + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const colors = this._themeService.colors;
|
||||
|
||||
let lineLength = lineData.getNoBgTrimmedLength();
|
||||
if (isCursorRow && lineLength < cursorX + 1) {
|
||||
lineLength = cursorX + 1;
|
||||
}
|
||||
|
||||
let charElement: HTMLSpanElement | undefined;
|
||||
let cellAmount = 0;
|
||||
let text = '';
|
||||
@@ -89,8 +80,7 @@ export class DomRendererRowFactory {
|
||||
|
||||
const isHover = linkState[0];
|
||||
|
||||
let x = 0;
|
||||
for (; x < lineLength; x++) {
|
||||
for (let x = 0; x < lineLength; x++) {
|
||||
lineData.loadCell(x, this._workCell);
|
||||
let width = this._workCell.getWidth();
|
||||
|
||||
@@ -129,6 +119,7 @@ export class DomRendererRowFactory {
|
||||
const isInSelection = this._isCellInSelection(x, row);
|
||||
const isCursorCell = isCursorRow && x === cursorX;
|
||||
const cc = cell.getCode();
|
||||
const isNull = cc === NULL_CELL_CODE && width === NULL_CELL_WIDTH;
|
||||
const isCombined = cell.isCombined();
|
||||
const isLinkHover = isHover && x >= linkState[1] && x <= linkState[2];
|
||||
|
||||
@@ -145,9 +136,9 @@ export class DomRendererRowFactory {
|
||||
* - underline from hover state did not change
|
||||
*/
|
||||
if (
|
||||
cellAmount && width === 1 && !isCombined
|
||||
cellAmount
|
||||
&& (isNull || (width === 1 && !isCombined && cc < 1424 && !metrics[cc]))
|
||||
&& cell.bg === oldBg && cell.fg === oldFg && cell.extended.ext === oldExt
|
||||
&& cc < 1424 && !metrics[cc]
|
||||
&& !isInSelection
|
||||
&& !isCursorCell
|
||||
&& isLinkHover === oldLinkHover
|
||||
@@ -166,7 +157,9 @@ export class DomRendererRowFactory {
|
||||
} else {
|
||||
if (cellAmount) {
|
||||
charElement.textContent = text;
|
||||
charElement.style.width = `${cellWidth * cellAmount}px`;
|
||||
if (cellAmount > 1) {
|
||||
charElement.style.width = `${cellWidth * cellAmount}px`;
|
||||
}
|
||||
}
|
||||
charElement = this._document.createElement('span');
|
||||
cellAmount = 0;
|
||||
@@ -385,7 +378,7 @@ export class DomRendererRowFactory {
|
||||
|
||||
|
||||
// account first char for later merge if it meets the start conditions
|
||||
if (width === 1 && !isCombined && cc < 1424 && !metrics[cc] && !isInSelection && !isCursorCell) {
|
||||
if ((isNull || (width === 1 && !isCombined && cc < 1424 && !metrics[cc])) && !isInSelection && !isCursorCell) {
|
||||
cellAmount++;
|
||||
} else {
|
||||
// every non-mergeable char gets directly written to its own span
|
||||
@@ -399,7 +392,13 @@ export class DomRendererRowFactory {
|
||||
// postfix width and text of last merged span
|
||||
if (charElement && cellAmount) {
|
||||
charElement.textContent = text;
|
||||
charElement.style.width = `${cellWidth * cellAmount}px`;
|
||||
/*
|
||||
* optimization: if the last merged span has no BG color set, use faster "width: auto",
|
||||
* else use correct px value for aligned BG coloring and BCE
|
||||
*/
|
||||
if (cellAmount > 1) {
|
||||
charElement.style.width = (oldBg & Attributes.CM_MASK) ? `${cellWidth * cellAmount}px`: 'auto';
|
||||
}
|
||||
}
|
||||
|
||||
return fragment;
|
||||
|
||||
Vendored
+1
@@ -242,6 +242,7 @@ export interface IBufferLine {
|
||||
copyFrom(line: IBufferLine): void;
|
||||
clone(): IBufferLine;
|
||||
getTrimmedLength(): number;
|
||||
getNoBgTrimmedLength(): number;
|
||||
translateToString(trimRight?: boolean, startCol?: number, endCol?: number): string;
|
||||
|
||||
/* direct access to cell attrs */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { CharData, IBufferLine, ICellData, IAttributeData, IExtendedAttrs } from 'common/Types';
|
||||
import { stringFromCodePoint } from 'common/input/TextDecoder';
|
||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, WHITESPACE_CELL_CHAR, Content, BgFlags, FgFlags } from 'common/buffer/Constants';
|
||||
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX, CHAR_DATA_ATTR_INDEX, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE, WHITESPACE_CELL_CHAR, Content, BgFlags, FgFlags, Attributes } from 'common/buffer/Constants';
|
||||
import { CellData } from 'common/buffer/CellData';
|
||||
import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData';
|
||||
|
||||
@@ -463,6 +463,15 @@ export class BufferLine implements IBufferLine {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public getNoBgTrimmedLength(): number {
|
||||
for (let i = this.length - 1; i >= 0; --i) {
|
||||
if ((this._data[i * CELL_SIZE + Cell.CONTENT] & Content.HAS_CONTENT_MASK) || (this._data[i * CELL_SIZE + Cell.BG] & Attributes.CM_MASK)) {
|
||||
return i + (this._data[i * CELL_SIZE + Cell.CONTENT] >> Content.WIDTH_SHIFT);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public copyCellsFrom(src: BufferLine, srcCol: number, destCol: number, length: number, applyInReverse: boolean): void {
|
||||
const srcData = src._data;
|
||||
if (applyInReverse) {
|
||||
|
||||
Reference in New Issue
Block a user