diff --git a/packages/diff-view/src/parts/GetContentLeftDom/GetContentLeftDom.ts b/packages/diff-view/src/parts/GetContentLeftDom/GetContentLeftDom.ts index 8dbc4e8..c78e351 100644 --- a/packages/diff-view/src/parts/GetContentLeftDom/GetContentLeftDom.ts +++ b/packages/diff-view/src/parts/GetContentLeftDom/GetContentLeftDom.ts @@ -6,21 +6,40 @@ import { defaultAllowedLinkSchemes } from '../AllowedLinkSchemes/AllowedLinkSche import * as ClassNames from '../ClassNames/ClassNames.ts' import { getContentDom } from '../GetContentDom/GetContentDom.ts' -export const getContentLeftDom = ( - contentLeft: string, - errorMessage = '', +interface GetContentLeftDomOptions { + readonly allowedLinkSchemes?: readonly string[] + readonly contentLeft: string + readonly errorCodeFrame?: string + readonly errorMessage?: string + readonly errorStack?: string + readonly inlineChanges?: readonly InlineDiffChange[] + readonly itemHeight?: number + readonly lineNumbers?: boolean + readonly maxLineY?: number + readonly minLineY?: number + readonly tokenizedLines?: readonly TokenizedLine[] + readonly totalLineCount?: number + readonly visibleLines?: readonly VisibleLine[] +} + +export const getContentLeftDom = ({ + allowedLinkSchemes = defaultAllowedLinkSchemes, + contentLeft, errorCodeFrame = '', + errorMessage = '', errorStack = '', - allowedLinkSchemes: readonly string[] = defaultAllowedLinkSchemes, + inlineChanges = [], + itemHeight = 20, lineNumbers = true, - totalLineCount = contentLeft ? contentLeft.split('\n').length : 1, + maxLineY, minLineY = 0, - maxLineY = totalLineCount, - inlineChanges: readonly InlineDiffChange[] = [], - tokenizedLines: readonly TokenizedLine[] = [], - visibleLines: readonly VisibleLine[] = [], - itemHeight = 20, -): readonly VirtualDomNode[] => { + tokenizedLines = [], + totalLineCount, + visibleLines = [], +}: GetContentLeftDomOptions): readonly VirtualDomNode[] => { + const resolvedTotalLineCount = totalLineCount ?? (contentLeft ? contentLeft.split('\n').length : 1) + const resolvedMaxLineY = maxLineY ?? resolvedTotalLineCount + return getContentDom( ClassNames.DiffEditorContentLeft, contentLeft, @@ -29,9 +48,9 @@ export const getContentLeftDom = ( errorStack, allowedLinkSchemes, lineNumbers, - totalLineCount, + resolvedTotalLineCount, minLineY, - maxLineY, + resolvedMaxLineY, inlineChanges, 'left', tokenizedLines, diff --git a/packages/diff-view/src/parts/GetContentRightDom/GetContentRightDom.ts b/packages/diff-view/src/parts/GetContentRightDom/GetContentRightDom.ts index 9bcfb77..91c3f84 100644 --- a/packages/diff-view/src/parts/GetContentRightDom/GetContentRightDom.ts +++ b/packages/diff-view/src/parts/GetContentRightDom/GetContentRightDom.ts @@ -6,21 +6,40 @@ import { defaultAllowedLinkSchemes } from '../AllowedLinkSchemes/AllowedLinkSche import * as ClassNames from '../ClassNames/ClassNames.ts' import { getContentDom } from '../GetContentDom/GetContentDom.ts' -export const getContentRightDom = ( - contentRight: string, - errorMessage = '', +interface GetContentRightDomOptions { + readonly allowedLinkSchemes?: readonly string[] + readonly contentRight: string + readonly errorCodeFrame?: string + readonly errorMessage?: string + readonly errorStack?: string + readonly inlineChanges?: readonly InlineDiffChange[] + readonly itemHeight?: number + readonly lineNumbers?: boolean + readonly maxLineY?: number + readonly minLineY?: number + readonly tokenizedLines?: readonly TokenizedLine[] + readonly totalLineCount?: number + readonly visibleLines?: readonly VisibleLine[] +} + +export const getContentRightDom = ({ + allowedLinkSchemes = defaultAllowedLinkSchemes, + contentRight, errorCodeFrame = '', + errorMessage = '', errorStack = '', - allowedLinkSchemes: readonly string[] = defaultAllowedLinkSchemes, + inlineChanges = [], + itemHeight = 20, lineNumbers = true, - totalLineCount = contentRight ? contentRight.split('\n').length : 1, + maxLineY, minLineY = 0, - maxLineY = totalLineCount, - inlineChanges: readonly InlineDiffChange[] = [], - tokenizedLines: readonly TokenizedLine[] = [], - visibleLines: readonly VisibleLine[] = [], - itemHeight = 20, -): readonly VirtualDomNode[] => { + tokenizedLines = [], + totalLineCount, + visibleLines = [], +}: GetContentRightDomOptions): readonly VirtualDomNode[] => { + const resolvedTotalLineCount = totalLineCount ?? (contentRight ? contentRight.split('\n').length : 1) + const resolvedMaxLineY = maxLineY ?? resolvedTotalLineCount + return getContentDom( ClassNames.DiffEditorContentRight, contentRight, @@ -29,9 +48,9 @@ export const getContentRightDom = ( errorStack, allowedLinkSchemes, lineNumbers, - totalLineCount, + resolvedTotalLineCount, minLineY, - maxLineY, + resolvedMaxLineY, inlineChanges, 'right', tokenizedLines, diff --git a/packages/diff-view/src/parts/GetDiffEditorVirtualDom/GetDiffEditorVirtualDom.ts b/packages/diff-view/src/parts/GetDiffEditorVirtualDom/GetDiffEditorVirtualDom.ts index 997d893..3e31bc6 100644 --- a/packages/diff-view/src/parts/GetDiffEditorVirtualDom/GetDiffEditorVirtualDom.ts +++ b/packages/diff-view/src/parts/GetDiffEditorVirtualDom/GetDiffEditorVirtualDom.ts @@ -45,36 +45,36 @@ export const getDiffEditorVirtualDom = (state: DiffViewState): readonly VirtualD const showLineNumbers = lineNumbers && renderModeLeft === 'text' && renderModeRight === 'text' const diffEditorLayoutClass = layout === 'vertical' ? ClassNames.DiffEditorVertical : ClassNames.DiffEditorHorizontal const sashLayoutClass = layout === 'vertical' ? ClassNames.SashHorizontal : ClassNames.SashVertical - const leftDom = getContentLeftDom( - contentLeft, - errorLeftMessage, - errorLeftCodeFrame, - errorLeftStack, + const leftDom = getContentLeftDom({ allowedLinkSchemes, - showLineNumbers, - totalLineCountLeft, - minLineY, - maxLineY, + contentLeft, + errorCodeFrame: errorLeftCodeFrame, + errorMessage: errorLeftMessage, + errorStack: errorLeftStack, inlineChanges, - tokenizedLinesLeft, - visibleLinesLeft, itemHeight, - ) - const rightDom = getContentRightDom( - contentRight, - errorRightMessage, - errorRightCodeFrame, - errorRightStack, - allowedLinkSchemes, - showLineNumbers, - totalLineCountRight, - minLineY, + lineNumbers: showLineNumbers, maxLineY, + minLineY, + tokenizedLines: tokenizedLinesLeft, + totalLineCount: totalLineCountLeft, + visibleLines: visibleLinesLeft, + }) + const rightDom = getContentRightDom({ + allowedLinkSchemes, + contentRight, + errorCodeFrame: errorRightCodeFrame, + errorMessage: errorRightMessage, + errorStack: errorRightStack, inlineChanges, - tokenizedLinesRight, - visibleLinesRight, itemHeight, - ) + lineNumbers: showLineNumbers, + maxLineY, + minLineY, + tokenizedLines: tokenizedLinesRight, + totalLineCount: totalLineCountRight, + visibleLines: visibleLinesRight, + }) const scrollBarDom = scrollBarActive ? getScrollBarDom() : [] const dom: readonly VirtualDomNode[] = [ { diff --git a/packages/diff-view/test/GetContentLeftDom.test.ts b/packages/diff-view/test/GetContentLeftDom.test.ts index 695e8b6..821dbd2 100644 --- a/packages/diff-view/test/GetContentLeftDom.test.ts +++ b/packages/diff-view/test/GetContentLeftDom.test.ts @@ -5,7 +5,14 @@ import * as ClassNames from '../src/parts/ClassNames/ClassNames.ts' import { getContentLeftDom } from '../src/parts/GetContentLeftDom/GetContentLeftDom.ts' test('getContentLeftDom renders each left line inside an EditorRow', (): void => { - const result = getContentLeftDom('before-content\nsecond-line', '', '', '', defaultAllowedLinkSchemes, true, 2, 0, 2) + const result = getContentLeftDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentLeft: 'before-content\nsecond-line', + lineNumbers: true, + maxLineY: 2, + minLineY: 0, + totalLineCount: 2, + }) expect(result).toEqual([ { @@ -56,7 +63,14 @@ test('getContentLeftDom renders each left line inside an EditorRow', (): void => }) test('getContentLeftDom omits the gutter when line numbers are disabled', (): void => { - const result = getContentLeftDom('before-content\nsecond-line', '', '', '', defaultAllowedLinkSchemes, false, 2, 0, 2) + const result = getContentLeftDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentLeft: 'before-content\nsecond-line', + lineNumbers: false, + maxLineY: 2, + minLineY: 0, + totalLineCount: 2, + }) expect(result).toEqual([ { @@ -85,7 +99,11 @@ test('getContentLeftDom omits the gutter when line numbers are disabled', (): vo }) test('getContentLeftDom renders load errors when available', (): void => { - const result = getContentLeftDom('', 'file not found', '', 'Error: file not found\n at read missing file (/tmp/missing-file.js:12:34)') + const result = getContentLeftDom({ + contentLeft: '', + errorMessage: 'file not found', + errorStack: 'Error: file not found\n at read missing file (/tmp/missing-file.js:12:34)', + }) expect(result).toEqual([ { @@ -132,11 +150,19 @@ test('getContentLeftDom renders load errors when available', (): void => { }) test('getContentLeftDom renders paired deletion and insertion on the same row', (): void => { - const result = getContentLeftDom('shared-line\ndeleted-line', '', '', '', defaultAllowedLinkSchemes, true, 2, 0, 2, [ - { leftIndex: 0, rightIndex: 0, type: 0 }, - { leftIndex: 1, rightIndex: 1, type: 2 }, - { leftIndex: 1, rightIndex: 1, type: 1 }, - ]) + const result = getContentLeftDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentLeft: 'shared-line\ndeleted-line', + inlineChanges: [ + { leftIndex: 0, rightIndex: 0, type: 0 }, + { leftIndex: 1, rightIndex: 1, type: 2 }, + { leftIndex: 1, rightIndex: 1, type: 1 }, + ], + lineNumbers: true, + maxLineY: 2, + minLineY: 0, + totalLineCount: 2, + }) expect(result).toEqual([ { @@ -187,19 +213,16 @@ test('getContentLeftDom renders paired deletion and insertion on the same row', }) test('getContentLeftDom renders syntax-highlighted token spans', (): void => { - const result = getContentLeftDom( - 'const answer = 1', - '', - '', - '', - defaultAllowedLinkSchemes, - true, - 1, - 0, - 1, - [], - [['const', 'Token Keyword', ' answer = 1', 'Token Text']], - ) + const result = getContentLeftDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentLeft: 'const answer = 1', + inlineChanges: [], + lineNumbers: true, + maxLineY: 1, + minLineY: 0, + tokenizedLines: [['const', 'Token Keyword', ' answer = 1', 'Token Text']], + totalLineCount: 1, + }) expect(result).toEqual([ { diff --git a/packages/diff-view/test/GetContentRightDom.test.ts b/packages/diff-view/test/GetContentRightDom.test.ts index b13dfd2..087bd86 100644 --- a/packages/diff-view/test/GetContentRightDom.test.ts +++ b/packages/diff-view/test/GetContentRightDom.test.ts @@ -5,7 +5,14 @@ import * as ClassNames from '../src/parts/ClassNames/ClassNames.ts' import { getContentRightDom } from '../src/parts/GetContentRightDom/GetContentRightDom.ts' test('getContentRightDom renders each right line inside an EditorRow', (): void => { - const result = getContentRightDom('after-content\nsecond-line', '', '', '', defaultAllowedLinkSchemes, true, 2, 0, 2) + const result = getContentRightDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentRight: 'after-content\nsecond-line', + lineNumbers: true, + maxLineY: 2, + minLineY: 0, + totalLineCount: 2, + }) expect(result).toEqual([ { @@ -56,7 +63,10 @@ test('getContentRightDom renders each right line inside an EditorRow', (): void }) test('getContentRightDom renders load errors when available', (): void => { - const result = getContentRightDom('', 'permission denied', '', '') + const result = getContentRightDom({ + contentRight: '', + errorMessage: 'permission denied', + }) expect(result).toEqual([ { @@ -79,11 +89,19 @@ test('getContentRightDom renders load errors when available', (): void => { }) test('getContentRightDom renders paired deletion and insertion on the same row', (): void => { - const result = getContentRightDom('shared-line\nadded-line', '', '', '', defaultAllowedLinkSchemes, true, 2, 0, 2, [ - { leftIndex: 0, rightIndex: 0, type: 0 }, - { leftIndex: 1, rightIndex: 1, type: 2 }, - { leftIndex: 1, rightIndex: 1, type: 1 }, - ]) + const result = getContentRightDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentRight: 'shared-line\nadded-line', + inlineChanges: [ + { leftIndex: 0, rightIndex: 0, type: 0 }, + { leftIndex: 1, rightIndex: 1, type: 2 }, + { leftIndex: 1, rightIndex: 1, type: 1 }, + ], + lineNumbers: true, + maxLineY: 2, + minLineY: 0, + totalLineCount: 2, + }) expect(result).toEqual([ { @@ -134,19 +152,16 @@ test('getContentRightDom renders paired deletion and insertion on the same row', }) test('getContentRightDom renders syntax-highlighted token spans', (): void => { - const result = getContentRightDom( - 'const answer = 1', - '', - '', - '', - defaultAllowedLinkSchemes, - true, - 1, - 0, - 1, - [], - [['const', 'Token Keyword', ' answer = 1', 'Token Text']], - ) + const result = getContentRightDom({ + allowedLinkSchemes: defaultAllowedLinkSchemes, + contentRight: 'const answer = 1', + inlineChanges: [], + lineNumbers: true, + maxLineY: 1, + minLineY: 0, + tokenizedLines: [['const', 'Token Keyword', ' answer = 1', 'Token Text']], + totalLineCount: 1, + }) expect(result).toEqual([ {