From 15ee1955f755ada34c9880098e4c56d4eb6d7dfc Mon Sep 17 00:00:00 2001 From: Le Vivilet Date: Wed, 29 Apr 2026 15:24:54 +0200 Subject: [PATCH] feat: add scrollBarBackgroundImage to DiffViewState and related functionality --- .../CreateDefaultState/CreateDefaultState.ts | 1 + packages/diff-view/src/parts/DiffCss/DiffCss.ts | 1 + .../src/parts/DiffViewState/DiffViewState.ts | 1 + .../src/parts/ReloadContent/ReloadContent.ts | 3 +++ .../diff-view/src/parts/RenderCss/RenderCss.ts | 4 +--- .../src/parts/SetDiffMode/SetDiffMode.ts | 3 +++ packages/diff-view/test/DiffCss.test.ts | 16 ++++++++++++++++ packages/diff-view/test/RenderCss.test.ts | 15 +++++++++++++++ 8 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 packages/diff-view/test/DiffCss.test.ts diff --git a/packages/diff-view/src/parts/CreateDefaultState/CreateDefaultState.ts b/packages/diff-view/src/parts/CreateDefaultState/CreateDefaultState.ts index 38e124f..e73e10b 100644 --- a/packages/diff-view/src/parts/CreateDefaultState/CreateDefaultState.ts +++ b/packages/diff-view/src/parts/CreateDefaultState/CreateDefaultState.ts @@ -51,6 +51,7 @@ export const createDefaultState = (): DiffViewState => ({ rightWidth: 48, root: '/', scrollBarActive: false, + scrollBarBackgroundImage: 'none', scrollBarDragOffsetY: 0, scrollBarHeight: 0, splitButtonEnabled: false, diff --git a/packages/diff-view/src/parts/DiffCss/DiffCss.ts b/packages/diff-view/src/parts/DiffCss/DiffCss.ts index 6ffe156..a3a81e4 100644 --- a/packages/diff-view/src/parts/DiffCss/DiffCss.ts +++ b/packages/diff-view/src/parts/DiffCss/DiffCss.ts @@ -13,6 +13,7 @@ export const isEqual = (oldState: DiffViewState, newState: DiffViewState): boole oldState.maxLineY === newState.maxLineY && oldState.minLineY === newState.minLineY && oldState.rightWidth === newState.rightWidth && + oldState.scrollBarBackgroundImage === newState.scrollBarBackgroundImage && oldState.scrollBarHeight === newState.scrollBarHeight && oldState.totalLineCount === newState.totalLineCount ) diff --git a/packages/diff-view/src/parts/DiffViewState/DiffViewState.ts b/packages/diff-view/src/parts/DiffViewState/DiffViewState.ts index e2db287..9b428a1 100644 --- a/packages/diff-view/src/parts/DiffViewState/DiffViewState.ts +++ b/packages/diff-view/src/parts/DiffViewState/DiffViewState.ts @@ -56,6 +56,7 @@ export interface DiffViewState { readonly rightWidth: number readonly root: string readonly scrollBarActive: boolean + readonly scrollBarBackgroundImage: string readonly scrollBarDragOffsetY: number readonly scrollBarHeight: number readonly splitButtonEnabled: boolean diff --git a/packages/diff-view/src/parts/ReloadContent/ReloadContent.ts b/packages/diff-view/src/parts/ReloadContent/ReloadContent.ts index 39da107..4a5d118 100644 --- a/packages/diff-view/src/parts/ReloadContent/ReloadContent.ts +++ b/packages/diff-view/src/parts/ReloadContent/ReloadContent.ts @@ -3,6 +3,7 @@ import { getGutterWidthVariable } from '../GetGutterWidthVariable/GetGutterWidth import { getInlineDiffState } from '../GetInlineDiffState/GetInlineDiffState.ts' import { getLineCount } from '../GetLineCount/GetLineCount.ts' import { getRenderMode } from '../GetRenderMode/GetRenderMode.ts' +import { getScrollBarBackgroundImage } from '../GetScrollBarBackgroundImage/GetScrollBarBackgroundImage.ts' import { getScrollState } from '../GetScrollState/GetScrollState.ts' import { getDisplayedContent } from '../GetTotalLineCount/GetTotalLineCount.ts' import { getVisibleLinesState } from '../GetVisibleLinesState/GetVisibleLinesState.ts' @@ -54,6 +55,7 @@ export const reloadContent = async ( const syntaxHighlightingState = canHighlightLeft || canHighlightRight ? await loadSyntaxHighlighting(contentLeft, contentRight, uriLeft, uriRight, platform, assetDir) : undefined const [imageSrcLeft, imageSrcRight] = await loadImages(renderModeLeft, renderModeRight, errorLeftMessage, errorRightMessage, uriLeft, uriRight) + const scrollBarBackgroundImage = getScrollBarBackgroundImage(inlineChanges, totalLineCount) const nextState = { ...state, @@ -74,6 +76,7 @@ export const reloadContent = async ( languageIdRight: syntaxHighlightingState?.languageIdRight || 'unknown', renderModeLeft, renderModeRight, + scrollBarBackgroundImage, tokenizedLinesLeft: syntaxHighlightingState?.tokenizedLinesLeft || [], tokenizedLinesRight: syntaxHighlightingState?.tokenizedLinesRight || [], totalLineCount, diff --git a/packages/diff-view/src/parts/RenderCss/RenderCss.ts b/packages/diff-view/src/parts/RenderCss/RenderCss.ts index a42f41e..79f1c80 100644 --- a/packages/diff-view/src/parts/RenderCss/RenderCss.ts +++ b/packages/diff-view/src/parts/RenderCss/RenderCss.ts @@ -2,13 +2,11 @@ import { ViewletCommand } from '@lvce-editor/constants' import type { DiffViewState } from '../DiffViewState/DiffViewState.ts' import { getCss } from '../GetCss/GetCss.ts' import { getSashWidth } from '../GetPaneWidths/GetPaneWidths.ts' -import { getScrollBarBackgroundImage } from '../GetScrollBarBackgroundImage/GetScrollBarBackgroundImage.ts' import { getScrollBarThumbTop } from '../GetScrollBarThumbTop/GetScrollBarThumbTop.ts' export const renderCss = (oldState: DiffViewState, newState: DiffViewState): any => { - const { deltaY, finalDeltaY, gutterWidthVariable, height, id, inlineChanges, itemHeight, leftWidth, rightWidth, scrollBarHeight, totalLineCount } = newState + const { deltaY, finalDeltaY, gutterWidthVariable, height, id, itemHeight, leftWidth, rightWidth, scrollBarBackgroundImage, scrollBarHeight } = newState const scrollBarThumbTop = getScrollBarThumbTop(height, scrollBarHeight, deltaY, finalDeltaY) - const scrollBarBackgroundImage = getScrollBarBackgroundImage(inlineChanges, totalLineCount) const { layout } = newState const staticCss = getCss() const gutterWidth = 'var(--GutterWidth)' diff --git a/packages/diff-view/src/parts/SetDiffMode/SetDiffMode.ts b/packages/diff-view/src/parts/SetDiffMode/SetDiffMode.ts index 47cdc28..7551b3a 100644 --- a/packages/diff-view/src/parts/SetDiffMode/SetDiffMode.ts +++ b/packages/diff-view/src/parts/SetDiffMode/SetDiffMode.ts @@ -1,4 +1,5 @@ import type { DiffMode, DiffViewState } from '../DiffViewState/DiffViewState.ts' +import { getScrollBarBackgroundImage } from '../GetScrollBarBackgroundImage/GetScrollBarBackgroundImage.ts' import { getScrollState } from '../GetScrollState/GetScrollState.ts' import { getTotalLineCount } from '../GetTotalLineCount/GetTotalLineCount.ts' import { getVisibleLinesState } from '../GetVisibleLinesState/GetVisibleLinesState.ts' @@ -22,9 +23,11 @@ export const setDiffMode = (state: DiffViewState, diffMode: DiffMode): DiffViewS state.renderModeRight, ) const scrollState = getScrollState(state.height, state.itemHeight, totalLineCount, state.minimumSliderSize, state.deltaY) + const scrollBarBackgroundImage = getScrollBarBackgroundImage(state.inlineChanges, totalLineCount) const nextState = { ...state, diffMode, + scrollBarBackgroundImage, totalLineCount, ...scrollState, } diff --git a/packages/diff-view/test/DiffCss.test.ts b/packages/diff-view/test/DiffCss.test.ts new file mode 100644 index 0000000..8838706 --- /dev/null +++ b/packages/diff-view/test/DiffCss.test.ts @@ -0,0 +1,16 @@ +import { expect, test } from '@jest/globals' +import { createDefaultState } from '../src/parts/CreateDefaultState/CreateDefaultState.ts' +import { isEqual } from '../src/parts/DiffCss/DiffCss.ts' + +test('isEqual returns false when cached scroll bar background image changes', (): void => { + const oldState = { + ...createDefaultState(), + scrollBarBackgroundImage: 'none', + } + const newState = { + ...oldState, + scrollBarBackgroundImage: 'linear-gradient(to bottom, transparent 0%, red 0%, red 50%, transparent 50%)', + } + + expect(isEqual(oldState, newState)).toBe(false) +}) diff --git a/packages/diff-view/test/RenderCss.test.ts b/packages/diff-view/test/RenderCss.test.ts index 50a53de..c46bb5c 100644 --- a/packages/diff-view/test/RenderCss.test.ts +++ b/packages/diff-view/test/RenderCss.test.ts @@ -3,6 +3,21 @@ import { ViewletCommand } from '@lvce-editor/constants' import { createDefaultState } from '../src/parts/CreateDefaultState/CreateDefaultState.ts' import { renderCss } from '../src/parts/RenderCss/RenderCss.ts' +test('renderCss uses cached scroll bar background image from state', (): void => { + const oldState = createDefaultState() + const newState = { + ...oldState, + id: 1, + scrollBarBackgroundImage: 'linear-gradient(to bottom, transparent 10%, red 10%, red 20%, transparent 20%)', + } + + const result = renderCss(oldState, newState) + + expect(result[0]).toBe(ViewletCommand.SetCss) + expect(result[1]).toBe(1) + expect(result[2]).toContain('--ScrollBarBackgroundImage: linear-gradient(to bottom, transparent 10%, red 10%, red 20%, transparent 20%);') +}) + test.skip('renderCss renders left and right widths as css variables', (): void => { const oldState = createDefaultState() const newState = {