From 7eead4404848878e5bd3cadd6fb88c0138ae3db5 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sun, 9 Oct 2022 08:14:56 -0700 Subject: [PATCH] Add onMultipleOptionChange --- src/browser/services/CharSizeService.ts | 2 ++ src/common/TestUtils.test.ts | 8 +++++ src/common/services/OptionsService.test.ts | 35 ++++++++++++++++++++++ src/common/services/OptionsService.ts | 9 ++++++ src/common/services/Services.ts | 8 +++++ 5 files changed, 62 insertions(+) diff --git a/src/browser/services/CharSizeService.ts b/src/browser/services/CharSizeService.ts index 267a361b..c75b8de0 100644 --- a/src/browser/services/CharSizeService.ts +++ b/src/browser/services/CharSizeService.ts @@ -27,6 +27,8 @@ export class CharSizeService extends Disposable implements ICharSizeService { ) { super(); this._measureStrategy = new DomMeasureStrategy(document, parentElement, this._optionsService); + // TODO: ... + // this.register(this._optionsService.onSpecificOptionChange( } public measure(): void { diff --git a/src/common/TestUtils.test.ts b/src/common/TestUtils.test.ts index 050b1cec..3aa0f694 100644 --- a/src/common/TestUtils.test.ts +++ b/src/common/TestUtils.test.ts @@ -129,6 +129,14 @@ export class MockOptionsService implements IOptionsService { } }); } + // eslint-disable-next-line @typescript-eslint/naming-convention + public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable { + return this.onOptionChange(eventKey => { + if (keys.indexOf(eventKey) !== -1) { + listener(); + } + }); + } public setOptions(options: ITerminalOptions): void { for (const key of Object.keys(options)) { this.options[key] = options[key]; diff --git a/src/common/services/OptionsService.test.ts b/src/common/services/OptionsService.test.ts index a0351516..004f7316 100644 --- a/src/common/services/OptionsService.test.ts +++ b/src/common/services/OptionsService.test.ts @@ -112,4 +112,39 @@ describe('OptionsService', () => { }); }); }); + describe('onSpecificOptionChange', () => { + let service: OptionsService; + beforeEach(() => { + service = new OptionsService({}); + }); + it('should fire only on a specific option change', async () => { + await new Promise(r => { + service.onSpecificOptionChange('scrollback', e => { + assert.strictEqual(e, 20); + r(); + }); + service.options.cursorWidth = 10; + service.options.scrollback = 20; + }); + }); + }); + describe('onMultipleOptionChange', () => { + let service: OptionsService; + beforeEach(() => { + service = new OptionsService({}); + }); + it('should fire only for specific options', async () => { + await new Promise(r => { + let called = false; + service.onMultipleOptionChange(['scrollback'], () => { + called = true; + }); + service.options.cursorWidth = 10; + assert.notOk(called); + service.options.scrollback = 20; + assert.ok(called); + r(); + }); + }); + }); }); diff --git a/src/common/services/OptionsService.ts b/src/common/services/OptionsService.ts index 439d6a77..976cdf8d 100644 --- a/src/common/services/OptionsService.ts +++ b/src/common/services/OptionsService.ts @@ -91,6 +91,15 @@ export class OptionsService extends Disposable implements IOptionsService { }); } + // eslint-disable-next-line @typescript-eslint/naming-convention + public onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable { + return this.onOptionChange(eventKey => { + if (keys.indexOf(eventKey) !== -1) { + listener(); + } + }); + } + private _setupOptions(): void { const getter = (propName: string): any => { if (!(propName in DEFAULT_OPTIONS)) { diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index 5e6751e9..cc388063 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -201,6 +201,14 @@ export interface IOptionsService { */ // eslint-disable-next-line @typescript-eslint/naming-convention onSpecificOptionChange(key: T, listener: (arg1: Required[T]) => any): IDisposable; + + /** + * Adds an event listener for when a set of specific options change, this is a convenience method + * that is preferred over {@link onOptionChange} when multiple options are being listened to and + * handled the same way. + */ + // eslint-disable-next-line @typescript-eslint/naming-convention + onMultipleOptionChange(keys: (keyof ITerminalOptions)[], listener: () => any): IDisposable; } export type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number;