From 6c3b084fe946e9f5ae227d5ed993ad0f3d9ce770 Mon Sep 17 00:00:00 2001 From: UmairShahzad <18100099@lums.edu.pk> Date: Thu, 15 Aug 2019 07:41:23 +0500 Subject: [PATCH 1/8] added scroll bubbling on wheel and touch move events --- src/Terminal.ts | 10 ++++++---- src/TestUtils.test.ts | 4 ++-- src/browser/Types.d.ts | 4 ++-- src/browser/Viewport.ts | 30 ++++++++++++++++++++++++------ 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 6d23e16cb..10094200f 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1037,8 +1037,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp // the shell for example this.register(addDisposableDomListener(el, 'wheel', (ev: WheelEvent) => { if (this.mouseEvents) return; - this.viewport.onWheel(ev); - return this.cancel(ev); + if (!this.viewport.onWheel(ev)) { + return this.cancel(ev); + } })); this.register(addDisposableDomListener(el, 'touchstart', (ev: TouchEvent) => { @@ -1049,8 +1050,9 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this.register(addDisposableDomListener(el, 'touchmove', (ev: TouchEvent) => { if (this.mouseEvents) return; - this.viewport.onTouchMove(ev); - return this.cancel(ev); + if (!this.viewport.onTouchMove(ev)) { + return this.cancel(ev); + } })); } diff --git a/src/TestUtils.test.ts b/src/TestUtils.test.ts index 0ee948d53..4a8e98d61 100644 --- a/src/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -401,13 +401,13 @@ export class MockViewport implements IViewport { onThemeChange(colors: IColorSet): void { throw new Error('Method not implemented.'); } - onWheel(ev: WheelEvent): void { + onWheel(ev: WheelEvent): boolean { throw new Error('Method not implemented.'); } onTouchStart(ev: TouchEvent): void { throw new Error('Method not implemented.'); } - onTouchMove(ev: TouchEvent): void { + onTouchMove(ev: TouchEvent): boolean { throw new Error('Method not implemented.'); } syncScrollArea(): void { } diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 3f3a76376..894beb36c 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -37,9 +37,9 @@ export interface IViewport extends IDisposable { scrollBarWidth: number; syncScrollArea(): void; getLinesScrolled(ev: WheelEvent): number; - onWheel(ev: WheelEvent): void; + onWheel(ev: WheelEvent): boolean; onTouchStart(ev: TouchEvent): void; - onTouchMove(ev: TouchEvent): void; + onTouchMove(ev: TouchEvent): boolean; onThemeChange(colors: IColorSet): void; } diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 9625588d5..96ee96213 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -152,20 +152,34 @@ export class Viewport extends Disposable implements IViewport { this._scrollLines(diff, true); } + + private _bubbleScroll(amount: number): boolean { + const scrollPosFromTop = this._viewportElement.scrollTop + this._lastRecordedViewportHeight; + if ((amount < 0 && this._viewportElement.scrollTop !== 0) || + (amount > 0 && scrollPosFromTop < this._lastRecordedBufferHeight)) { + return false; + } + return true; + } + /** * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual * scrolling to `onScroll`, this event needs to be attached manually by the consumer of * `Viewport`. * @param ev The mouse wheel event. */ - public onWheel(ev: WheelEvent): void { + public onWheel(ev: WheelEvent): boolean { const amount = this._getPixelsScrolled(ev); if (amount === 0) { - return; + return false; } this._viewportElement.scrollTop += amount; // Prevent the page from scrolling when the terminal scrolls - ev.preventDefault(); + const shouldBubbleEvent = this._bubbleScroll(amount); + if (!shouldBubbleEvent && ev.cancelable) { + ev.preventDefault(); + } + return shouldBubbleEvent; } private _getPixelsScrolled(ev: WheelEvent): number { @@ -220,13 +234,17 @@ export class Viewport extends Disposable implements IViewport { * Handles the touchmove event, scrolling the viewport if the position shifted. * @param ev The touch event. */ - public onTouchMove(ev: TouchEvent): void { + public onTouchMove(ev: TouchEvent): boolean { const deltaY = this._lastTouchY - ev.touches[0].pageY; this._lastTouchY = ev.touches[0].pageY; if (deltaY === 0) { - return; + return false; } this._viewportElement.scrollTop += deltaY; - ev.preventDefault(); + const shouldBubbleEvent = this._bubbleScroll(deltaY); + if (!shouldBubbleEvent && ev.cancelable) { + ev.preventDefault(); + } + return shouldBubbleEvent; } } From 582934390d3794507cef8034a7df9f468f7ac0c4 Mon Sep 17 00:00:00 2001 From: UmairShahzad <18100099@lums.edu.pk> Date: Wed, 21 Aug 2019 00:57:41 +0500 Subject: [PATCH 2/8] restructured bubble scroll --- src/browser/Viewport.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 96ee96213..0d441ebe9 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -152,12 +152,19 @@ export class Viewport extends Disposable implements IViewport { this._scrollLines(diff, true); } - - private _bubbleScroll(amount: number): boolean { + /** + * Handles bubbling of scroll event in case the viewport has reached top or bottom + * @param ev The scroll event. + * @param amount The amount scrolled + */ + private _bubbleScroll(ev: Event, amount: number): boolean { const scrollPosFromTop = this._viewportElement.scrollTop + this._lastRecordedViewportHeight; if ((amount < 0 && this._viewportElement.scrollTop !== 0) || (amount > 0 && scrollPosFromTop < this._lastRecordedBufferHeight)) { - return false; + if (ev.cancelable) { + ev.preventDefault(); + } + return false; } return true; } @@ -174,12 +181,7 @@ export class Viewport extends Disposable implements IViewport { return false; } this._viewportElement.scrollTop += amount; - // Prevent the page from scrolling when the terminal scrolls - const shouldBubbleEvent = this._bubbleScroll(amount); - if (!shouldBubbleEvent && ev.cancelable) { - ev.preventDefault(); - } - return shouldBubbleEvent; + return this._bubbleScroll(ev, amount); } private _getPixelsScrolled(ev: WheelEvent): number { @@ -241,10 +243,6 @@ export class Viewport extends Disposable implements IViewport { return false; } this._viewportElement.scrollTop += deltaY; - const shouldBubbleEvent = this._bubbleScroll(deltaY); - if (!shouldBubbleEvent && ev.cancelable) { - ev.preventDefault(); - } - return shouldBubbleEvent; + return this._bubbleScroll(ev, deltaY); } } From 441d27cb5acb8e31961dbc4b041d04dfc41cf18a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 22 Aug 2019 08:39:02 -0700 Subject: [PATCH 3/8] Expose paste API Fixes #2390 --- src/Terminal.test.ts | 25 +++++++++++++++++++++++++ src/Terminal.ts | 8 ++++++-- src/TestUtils.test.ts | 3 +++ src/Types.d.ts | 1 + src/browser/Clipboard.ts | 24 +++++++++++------------- src/public/Terminal.ts | 3 +++ typings/xterm.d.ts | 6 ++++++ 7 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index e0f9f8788..f157cd32d 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -224,6 +224,31 @@ describe('Terminal', () => { }); }); + describe('paste', () => { + it('should fire data event', done => { + term.onData(e => { + assert.equal(e, 'foo'); + done(); + }); + term.paste('foo'); + }); + it('should sanitize \n chars', done => { + term.onData(e => { + assert.equal(e, '\rfoo\r'); + done(); + }); + term.paste('\r\nfoo\n'); + }); + it('should respect bracketed paste mode', done => { + term.onData(e => { + assert.equal(e, '\x1b[200~foo\x1b[201~'); + done(); + }); + term.write('\x1b[?2004h'); + term.paste('foo'); + }); + }); + describe('scroll', () => { describe('scrollLines', () => { let startYDisp: number; diff --git a/src/Terminal.ts b/src/Terminal.ts index 90c4b2862..731846f24 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -25,7 +25,7 @@ import { IInputHandlingTerminal, ICompositionHelper, ITerminalOptions, ITerminal import { IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types'; import { CompositionHelper } from 'browser/input/CompositionHelper'; import { Viewport } from 'browser/Viewport'; -import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from 'browser/Clipboard'; +import { rightClickHandler, moveTextAreaUnderMouseCursor, handlePasteEvent, copyHandler, paste } from 'browser/Clipboard'; import { C0 } from 'common/data/EscapeSequences'; import { InputHandler } from './InputHandler'; import { Renderer } from './renderer/Renderer'; @@ -498,7 +498,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp } copyHandler(event, this._selectionService); })); - const pasteHandlerWrapper = (event: ClipboardEvent) => pasteHandler(event, this.textarea, this.bracketedPasteMode, e => this._coreService.triggerDataEvent(e, true)); + const pasteHandlerWrapper = (event: ClipboardEvent) => handlePasteEvent(event, this.textarea, this.bracketedPasteMode, this._coreService); this.register(addDisposableDomListener(this.textarea, 'paste', pasteHandlerWrapper)); this.register(addDisposableDomListener(this.element, 'paste', pasteHandlerWrapper)); @@ -1387,6 +1387,10 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this.write(data + '\r\n'); } + public paste(data: string): void { + paste(data, this.textarea, this.bracketedPasteMode, this._coreService); + } + /** * Attaches a custom key event handler which is run before keys are processed, * giving consumers of xterm.js ultimate control as to what keys should be diff --git a/src/TestUtils.test.ts b/src/TestUtils.test.ts index 7d03126d3..9a406a08a 100644 --- a/src/TestUtils.test.ts +++ b/src/TestUtils.test.ts @@ -68,6 +68,9 @@ export class MockTerminal implements ITerminal { writeln(data: string): void { throw new Error('Method not implemented.'); } + paste(data: string): void { + throw new Error('Method not implemented.'); + } open(parent: HTMLElement): void { throw new Error('Method not implemented.'); } diff --git a/src/Types.d.ts b/src/Types.d.ts index bb203b525..8b933874e 100644 --- a/src/Types.d.ts +++ b/src/Types.d.ts @@ -226,6 +226,7 @@ export interface IPublicTerminal extends IDisposable { clear(): void; write(data: string): void; writeUtf8(data: Uint8Array): void; + paste(data: string): void; refresh(start: number, end: number): void; reset(): void; } diff --git a/src/browser/Clipboard.ts b/src/browser/Clipboard.ts index f56868ccc..594e4429e 100644 --- a/src/browser/Clipboard.ts +++ b/src/browser/Clipboard.ts @@ -4,6 +4,7 @@ */ import { ISelectionService } from 'browser/services/Services'; +import { ICoreService } from 'common/services/Services'; /** * Prepares text to be pasted into the terminal by normalizing the line endings @@ -41,24 +42,21 @@ export function copyHandler(ev: ClipboardEvent, selectionService: ISelectionServ * @param ev The original paste event to be handled * @param term The terminal on which to apply the handled paste event */ -export function pasteHandler(ev: ClipboardEvent, textarea: HTMLTextAreaElement, bracketedPasteMode: boolean, triggerUserInput: (data: string) => void): void { +export function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, bracketedPasteMode: boolean, coreService: ICoreService): void { ev.stopPropagation(); - - let text: string; - - const dispatchPaste = function(text: string): void { - text = prepareTextForTerminal(text); - text = bracketTextForPaste(text, bracketedPasteMode); - triggerUserInput(text); - textarea.value = ''; - }; - if (ev.clipboardData) { - text = ev.clipboardData.getData('text/plain'); - dispatchPaste(text); + const text = ev.clipboardData.getData('text/plain'); + paste(text, textarea, bracketedPasteMode, coreService); } } +export function paste(text: string, textarea: HTMLTextAreaElement, bracketedPasteMode: boolean, coreService: ICoreService): void { + text = prepareTextForTerminal(text); + text = bracketTextForPaste(text, bracketedPasteMode); + coreService.triggerDataEvent(text, true); + textarea.value = ''; +} + /** * Moves the textarea under the mouse cursor and focuses it. * @param ev The original right click event to be handled. diff --git a/src/public/Terminal.ts b/src/public/Terminal.ts index 33644e5d3..6d6cedcac 100644 --- a/src/public/Terminal.ts +++ b/src/public/Terminal.ts @@ -134,6 +134,9 @@ export class Terminal implements ITerminalApi { public writeUtf8(data: Uint8Array): void { this._core.writeUtf8(data); } + public paste(data: string): void { + this._core.paste(data); + } public getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'fontWeight' | 'fontWeightBold' | 'logLevel' | 'rendererType' | 'termName' | 'wordSeparator'): string; public getOption(key: 'allowTransparency' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'disableStdin' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'screenKeys' | 'useFlowControl' | 'visualBell'): boolean; public getOption(key: 'colors'): string[]; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 4ec6fc1c2..cae54dc17 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -669,6 +669,12 @@ declare module 'xterm' { */ writeUtf8(data: Uint8Array): void; + /** + * Writes text to the terminal, performing the necessary transformations for pasted text. + * @param data The text to write to the terminal. + */ + paste(data: string): void; + /** * Retrieves an option's value from the terminal. * @param key The option key. From 9c7cf8e6e668212e56e0aebed2c593800c444544 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 22 Aug 2019 08:39:50 -0700 Subject: [PATCH 4/8] Cover another paste case --- src/Terminal.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index f157cd32d..59864f0a3 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -234,10 +234,10 @@ describe('Terminal', () => { }); it('should sanitize \n chars', done => { term.onData(e => { - assert.equal(e, '\rfoo\r'); + assert.equal(e, '\rfoo\rbar\r'); done(); }); - term.paste('\r\nfoo\n'); + term.paste('\r\nfoo\nbar\r'); }); it('should respect bracketed paste mode', done => { term.onData(e => { From a2d890cf7438a4d392a7f05ffa9b5cfd2995c49d Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 22 Aug 2019 08:54:28 -0700 Subject: [PATCH 5/8] Add paste api integration tests --- test/api/Terminal.api.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/api/Terminal.api.ts b/test/api/Terminal.api.ts index e536e88af..b2157b1ef 100644 --- a/test/api/Terminal.api.ts +++ b/test/api/Terminal.api.ts @@ -76,6 +76,22 @@ describe('API Integration Tests', function(): void { assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'foobaræ–‡'); }); + it('paste', async function(): Promise { + await openTerminal(); + await page.evaluate(` + window.calls = []; + window.term.onData(e => calls.push(e)); + window.term.paste('foo'); + window.term.paste('\\r\\nfoo\\nbar\\r'); + window.term.write('\\x1b[?2004h'); + // TODO: Use promise/callback for write when we support that + // Force sync write + window.term._core._innerWrite(); + window.term.paste('foo'); + `); + assert.deepEqual(await page.evaluate(`window.calls`), ['foo', '\rfoo\rbar\r', '\x1b[200~foo\x1b[201~']); + }); + it('clear', async function(): Promise { await openTerminal({ rows: 5 }); await page.evaluate(` From f91aa75c80bae8855a9e57f61f35077447462df5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 22 Aug 2019 09:12:04 -0700 Subject: [PATCH 6/8] Indent second line of if condition --- src/browser/Viewport.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 0d441ebe9..4f9363d99 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -160,7 +160,7 @@ export class Viewport extends Disposable implements IViewport { private _bubbleScroll(ev: Event, amount: number): boolean { const scrollPosFromTop = this._viewportElement.scrollTop + this._lastRecordedViewportHeight; if ((amount < 0 && this._viewportElement.scrollTop !== 0) || - (amount > 0 && scrollPosFromTop < this._lastRecordedBufferHeight)) { + (amount > 0 && scrollPosFromTop < this._lastRecordedBufferHeight)) { if (ev.cancelable) { ev.preventDefault(); } From a7e64ad53762c64e9285788fa9cb7534d9db4f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 23 Aug 2019 15:32:05 +0200 Subject: [PATCH 7/8] fix bugs --- src/common/parser/EscapeSequenceParser.ts | 6 +-- src/common/parser/Params.test.ts | 55 +++++++++++++++-------- src/common/parser/Params.ts | 41 ++++++++--------- 3 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/common/parser/EscapeSequenceParser.ts b/src/common/parser/EscapeSequenceParser.ts index 55bac11ec..c789e9b44 100644 --- a/src/common/parser/EscapeSequenceParser.ts +++ b/src/common/parser/EscapeSequenceParser.ts @@ -543,20 +543,16 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP break; case ParserAction.PARAM: // inner loop: digits (0x30 - 0x39) and ; (0x3b) and : (0x3a) - let isSub = false; do { switch (code) { case 0x3b: params.addParam(0); // ZDM - isSub = false; break; case 0x3a: params.addSubParam(-1); - isSub = true; break; default: // 0x30 - 0x39 - if (isSub) params.addSubParamDigit(code - 48); - else params.addParamDigit(code - 48); + params.addDigit(code - 48); } } while (++i < length && (code = data[i]) > 0x2f && code < 0x3c); i--; diff --git a/src/common/parser/Params.test.ts b/src/common/parser/Params.test.ts index 01287b8f7..2418fa452 100644 --- a/src/common/parser/Params.test.ts +++ b/src/common/parser/Params.test.ts @@ -16,27 +16,29 @@ class TestParams extends Params { } /** `Params` parser shim */ -function parse(params: Params, s: string): void { +function parse(params: Params, s: string | string[]): void { params.reset(); params.addParam(0); - let isSub = false; - for (let i = 0; i < s.length; ++i) { - let code = s.charCodeAt(i); - do { - switch (code) { - case 0x3b: - params.addParam(0); - isSub = false; - break; - case 0x3a: - params.addSubParam(-1); - isSub = true; - break; - default: // 0x30 - 0x39 - if (isSub) params.addSubParamDigit(code - 48); - else params.addParamDigit(code - 48); - } - } while (++i < s.length && (code = s.charCodeAt(i)) > 0x2f && code < 0x3c); + if (typeof s === 'string') { + s = [s]; + } + for (const chunk of s) { + for (let i = 0; i < chunk.length; ++i) { + let code = chunk.charCodeAt(i); + do { + switch (code) { + case 0x3b: + params.addParam(0); + break; + case 0x3a: + params.addSubParam(-1); + break; + default: // 0x30 - 0x39 + params.addDigit(code - 48); + } + } while (++i < s.length && (code = chunk.charCodeAt(i)) > 0x2f && code < 0x3c); + i--; + } } } @@ -217,4 +219,19 @@ describe('Params', () => { assert.deepEqual(params.toArray(), [0, [0x7FFFFFFF]]); }); }); + describe('issue 2389', () => { + it('should cancel subdigits if beyond params limit', () => { + const params = new Params(); + parse(params, ';;;;;;;;;10;;;;;;;;;;20;;;;;;;;;;30;31;32;33;34;35::::::::'); + assert.deepEqual(params.toArray(), [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32]); + }); + it('should carry forward isSub state', () => { + const params = new Params(); + parse(params, ['1:22:33', '44']); + assert.deepEqual(params.toArray(), [1, [22, 3344]]); + }); + }); }); diff --git a/src/common/parser/Params.ts b/src/common/parser/Params.ts index 7ef8341a7..519458fac 100644 --- a/src/common/parser/Params.ts +++ b/src/common/parser/Params.ts @@ -41,6 +41,7 @@ export class Params implements IParams { private _subParamsIdx: Uint16Array; private _rejectDigits: boolean; private _rejectSubDigits: boolean; + private _digitIsSub: boolean; /** * Create a `Params` type from JS array representation. @@ -79,6 +80,7 @@ export class Params implements IParams { this._subParamsIdx = new Uint16Array(maxLength); this._rejectDigits = false; this._rejectSubDigits = false; + this._digitIsSub = false; } /** @@ -91,6 +93,9 @@ export class Params implements IParams { newParams._subParams.set(this._subParams); newParams._subParamsLength = this._subParamsLength; newParams._subParamsIdx.set(this._subParamsIdx); + newParams._rejectDigits = this._rejectDigits; + newParams._rejectSubDigits = this._rejectSubDigits; + newParams._digitIsSub = this._digitIsSub; return newParams; } @@ -121,6 +126,7 @@ export class Params implements IParams { this._subParamsLength = 0; this._rejectDigits = false; this._rejectSubDigits = false; + this._digitIsSub = false; } /** @@ -131,6 +137,7 @@ export class Params implements IParams { * store up to 30. */ public addParam(value: number): void { + this._digitIsSub = false; if (this.length >= this.maxLength) { this._rejectDigits = true; return; @@ -150,10 +157,11 @@ export class Params implements IParams { * sub parameter will be ignored. */ public addSubParam(value: number): void { + this._digitIsSub = true; if (!this.length) { return; } - if (this._subParamsLength >= this.maxSubParamsLength) { + if (this._rejectDigits || this._subParamsLength >= this.maxSubParamsLength) { this._rejectSubDigits = true; return; } @@ -204,30 +212,19 @@ export class Params implements IParams { /** * Add a single digit value to current parameter. * This is used by the parser to account digits on a char by char basis. - * Do not use this method directly, consider using `addParam` instead. + * Do not use this method directly, consider using `addParam` or `addSubParam` instead. */ - public addParamDigit(value: number): void { - if (this._rejectDigits) { + public addDigit(value: number): void { + let length; + if (this._rejectDigits + || !(length = this._digitIsSub ? this._subParamsLength : this.length) + || (this._digitIsSub && this._rejectSubDigits) + ) { return; } - const v = this.params[this.length - 1] * 10 + value; - this.params[this.length - 1] = v > MAX_VALUE ? MAX_VALUE : v; - } - /** - * Add a single digit value to current sub parameter. - * This is used by the parser to account digits on a char by char basis. - * Do not use this method directly, consider using `addSubParam` instead. - */ - public addSubParamDigit(value: number): void { - if (!this._subParamsLength || this._rejectDigits || this._rejectSubDigits) { - return; - } - if (this._subParams[this._subParamsLength - 1] === -1) { - this._subParams[this._subParamsLength - 1] = value; - } else { - const v = this._subParams[this._subParamsLength - 1] * 10 + value; - this._subParams[this._subParamsLength - 1] = v > MAX_VALUE ? MAX_VALUE : v; - } + const store = this._digitIsSub ? this._subParams : this.params; + const cur = store[length - 1]; + store[length - 1] = ~cur ? Math.min(cur * 10 + value, MAX_VALUE) : value; } } From 87eb942d3238d7a7d474ed4f020d8a9fea70a074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Fri, 23 Aug 2019 20:21:58 +0200 Subject: [PATCH 8/8] remove comment --- src/common/parser/Params.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/parser/Params.ts b/src/common/parser/Params.ts index 519458fac..47ee129d4 100644 --- a/src/common/parser/Params.ts +++ b/src/common/parser/Params.ts @@ -212,7 +212,6 @@ export class Params implements IParams { /** * Add a single digit value to current parameter. * This is used by the parser to account digits on a char by char basis. - * Do not use this method directly, consider using `addParam` or `addSubParam` instead. */ public addDigit(value: number): void { let length;