From 839271096e32c0b8d760a6665de96c9b05ff0a07 Mon Sep 17 00:00:00 2001 From: Jason Lin Date: Thu, 20 Oct 2022 15:06:12 +1100 Subject: [PATCH] Don't reset the url --- src/common/InputHandler.test.ts | 36 ++++++++++++++++++++++++++++++++- src/common/InputHandler.ts | 24 ++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index d9127e7b..f530ea20 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -8,7 +8,7 @@ import { InputHandler } from 'common/InputHandler'; import { IBufferLine, IAttributeData, IColorEvent, ColorIndex, ColorRequestType } from 'common/Types'; import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine'; import { CellData } from 'common/buffer/CellData'; -import { Attributes, UnderlineStyle } from 'common/buffer/Constants'; +import { Attributes, BgFlags, UnderlineStyle } from 'common/buffer/Constants'; import { AttributeData } from 'common/buffer/AttributeData'; import { Params } from 'common/parser/Params'; import { MockCoreService, MockBufferService, MockOptionsService, MockLogService, MockCoreMouseService, MockCharsetService, MockUnicodeService, MockOscLinkService } from 'common/TestUtils.test'; @@ -1689,6 +1689,40 @@ describe('InputHandler', () => { }); }); + describe.only('Reset text attributes (SGR 0)', () => { + it('resets every attributes if there is no url', async () => { + await inputHandler.parseP('\x1b[30m\x1b[40m\x1b[4m'); + assert.notEqual(inputHandler.curAttrData.fg, 0); + assert.notEqual(inputHandler.curAttrData.bg, 0); + assert.isFalse(inputHandler.curAttrData.extended.isEmpty()); + + await inputHandler.parseP('\x1b[m'); + assert.equal(inputHandler.curAttrData.fg, 0); + assert.equal(inputHandler.curAttrData.bg, 0); + assert.isTrue(inputHandler.curAttrData.extended.isEmpty()); + }); + + it('resets every attributes except for the url', async () => { + await inputHandler.parseP('\x1b[30m\x1b[40m\x1b[4m'); + await inputHandler.parseP('\x1b]8;;http://example.com\x1b\\'); + assert.notEqual(inputHandler.curAttrData.fg, 0); + assert.notEqual(inputHandler.curAttrData.bg, 0); + assert.notEqual(inputHandler.curAttrData.extended.ext, 0); + const urlId = inputHandler.curAttrData.extended.urlId; + assert.notEqual(urlId, 0); + + await inputHandler.parseP('\x1b[m'); + assert.equal(inputHandler.curAttrData.fg, 0); + assert.equal(inputHandler.curAttrData.bg, BgFlags.HAS_EXTENDED); + assert.equal(inputHandler.curAttrData.extended.urlId, urlId); + // Check that `extended._ext === 0`. Note that `extended.ext` does not + // equal `extended._ext` because it is affected by the url. + const extended = inputHandler.curAttrData.extended.clone(); + extended.urlId = 0; + assert.equal(extended.ext, 0); + }); + }); + describe('extended underline style support (SGR 4)', () => { beforeEach(() => { bufferService.resize(10, 5); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 5feaf2b6..8674e80a 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2356,6 +2356,22 @@ export class InputHandler extends Disposable implements IInputHandler { attr.updateExtended(); } + private _processSGR0(attr: IAttributeData): void { + attr.fg = DEFAULT_ATTR_DATA.fg; + attr.bg = DEFAULT_ATTR_DATA.bg; + + if (!attr.extended.isEmpty()) { + // Treat extended attrs as immutable, thus always clone from old one. + // This is needed since the buffer only holds references to it. + attr.extended = attr.extended.clone(); + attr.extended.ext = 0; + + if (attr.extended.urlId) { + attr.bg |= BgFlags.HAS_EXTENDED; + } + } + } + /** * CSI Pm m Character Attributes (SGR). * @@ -2441,9 +2457,7 @@ export class InputHandler extends Disposable implements IInputHandler { public charAttributes(params: IParams): boolean { // Optimize a single SGR0. if (params.length === 1 && params.params[0] === 0) { - this._curAttrData.fg = DEFAULT_ATTR_DATA.fg; - this._curAttrData.bg = DEFAULT_ATTR_DATA.bg; - this._curAttrData.extended = DEFAULT_ATTR_DATA.extended.clone(); + this._processSGR0(this._curAttrData); return true; } @@ -2471,9 +2485,7 @@ export class InputHandler extends Disposable implements IInputHandler { attr.bg |= Attributes.CM_P16 | (p - 100) | 8; } else if (p === 0) { // default - attr.fg = DEFAULT_ATTR_DATA.fg; - attr.bg = DEFAULT_ATTR_DATA.bg; - attr.extended = DEFAULT_ATTR_DATA.extended.clone(); + this._processSGR0(attr); } else if (p === 1) { // bold text attr.fg |= FgFlags.BOLD;