Skip to content

Commit 70506a3

Browse files
wip
1 parent a93e17f commit 70506a3

17 files changed

+846
-5
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<script lang="ts">
2+
import { DiffLineType, type DiffFile, type DiffLine, type File } from '@git-diff-view/core';
3+
import DiffSyntax from './DiffSyntax.svelte';
4+
import DiffString from './DiffString.svelte';
5+
6+
interface Props {
7+
rawLine: string;
8+
plainLine?: File['plainFile'][number];
9+
syntaxLine?: File['syntaxFile'][number];
10+
diffLine?: DiffLine;
11+
diffFile: DiffFile;
12+
enableWrap: boolean;
13+
enableHighlight: boolean;
14+
}
15+
16+
let props: Props = $props();
17+
18+
const isAdded = $derived.by(() => props.diffLine?.type === DiffLineType.Add);
19+
20+
const isDelete = $derived.by(() => props.diffLine?.type === DiffLineType.Delete);
21+
22+
const isMaxLineLengthToIgnoreSyntax = $derived.by(() => {
23+
return props.syntaxLine && props.syntaxLine?.nodeList?.length > 150;
24+
});
25+
26+
const isEnableTemplate = $derived.by(() => props.diffFile.getIsEnableTemplate());
27+
</script>
28+
29+
<div
30+
class="diff-line-content-item pl-[2.0em]"
31+
style={`
32+
white-space: ${props.enableWrap ? 'pre-wrap' : 'pre'},
33+
word-break: ${props.enableWrap ? 'break-all' : 'initial'}
34+
`}
35+
>
36+
<span
37+
data-operator={isAdded ? '+' : isDelete ? '-' : undefined}
38+
class="diff-line-content-operator ml-[-1.5em] inline-block w-[1.5em] select-none indent-[0.2em]"
39+
>
40+
{isAdded ? '+' : isDelete ? '-' : ' '}
41+
</span>
42+
{#if props.enableHighlight && props.syntaxLine && !isMaxLineLengthToIgnoreSyntax}
43+
<DiffSyntax
44+
operator={isAdded ? 'add' : isDelete ? 'del' : undefined}
45+
rawLine={props.rawLine}
46+
diffLine={props.diffLine}
47+
syntaxLine={props.syntaxLine}
48+
enableWrap={props.enableWrap}
49+
enableTemplate={isEnableTemplate}
50+
/>
51+
{:else}
52+
<DiffString
53+
operator={isAdded ? 'add' : isDelete ? 'del' : undefined}
54+
rawLine={props.rawLine}
55+
diffLine={props.diffLine}
56+
plainLine={props.plainLine}
57+
enableWrap={props.enableWrap}
58+
enableTemplate={isEnableTemplate}
59+
/>
60+
{/if}
61+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
interface Props {
3+
className?: string;
4+
}
5+
6+
let props: Props = $props();
7+
</script>
8+
9+
<svg
10+
aria-hidden="true"
11+
height="16"
12+
viewBox="0 0 16 16"
13+
version="1.1"
14+
width="16"
15+
class={props.className}
16+
>
17+
<path
18+
d="m8.177.677 2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25a.75.75 0 0 1-1.5 0V4H5.104a.25.25 0 0 1-.177-.427L7.823.677a.25.25 0 0 1 .354 0ZM7.25 10.75a.75.75 0 0 1 1.5 0V12h2.146a.25.25 0 0 1 .177.427l-2.896 2.896a.25.25 0 0 1-.354 0l-2.896-2.896A.25.25 0 0 1 5.104 12H7.25v-1.25Zm-5-2a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z"
19+
></path>
20+
</svg>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
interface Props {
3+
className?: string;
4+
}
5+
6+
let props: Props = $props();
7+
</script>
8+
9+
<svg
10+
aria-hidden="true"
11+
height="16"
12+
viewBox="0 0 16 16"
13+
version="1.1"
14+
width="16"
15+
class={props.className}
16+
>
17+
<path
18+
d="m8.177 14.323 2.896-2.896a.25.25 0 0 0-.177-.427H8.75V7.764a.75.75 0 1 0-1.5 0V11H5.104a.25.25 0 0 0-.177.427l2.896 2.896a.25.25 0 0 0 .354 0ZM2.25 5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 4.25a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5a.75.75 0 0 1 .75.75ZM8.25 5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 4.25a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5a.75.75 0 0 1 .75.75Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z"
19+
></path>
20+
</svg>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
interface Props {
3+
className?: string;
4+
}
5+
6+
let props: Props = $props();
7+
</script>
8+
9+
<svg
10+
aria-hidden="true"
11+
height="16"
12+
viewBox="0 0 16 16"
13+
version="1.1"
14+
width="16"
15+
class={props.className}
16+
>
17+
<path
18+
d="M7.823 1.677 4.927 4.573A.25.25 0 0 0 5.104 5H7.25v3.236a.75.75 0 1 0 1.5 0V5h2.146a.25.25 0 0 0 .177-.427L8.177 1.677a.25.25 0 0 0-.354 0ZM13.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5Zm-3.75.75a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75ZM7.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5ZM4 11.75a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75ZM1.75 11a.75.75 0 0 0 0 1.5h.5a.75.75 0 0 0 0-1.5h-.5Z"
19+
></path>
20+
</svg>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<svg
2+
aria-label="No newline at end of file"
3+
role="img"
4+
viewBox="0 0 16 16"
5+
version="1.1"
6+
fill="currentColor"
7+
>
8+
<path d="M4.25 7.25a.75.75 0 0 0 0 1.5h7.5a.75.75 0 0 0 0-1.5h-7.5Z"></path>
9+
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-1.5 0a6.5 6.5 0 1 0-13 0 6.5 6.5 0 0 0 13 0Z"
10+
></path>
11+
</svg>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<script lang="ts">
2+
import type { DiffFile, SplitSide } from '@git-diff-view/core';
3+
import { addWidgetBGName, addWidgetColorName, diffFontSizeName } from '@git-diff-view/utils';
4+
5+
interface Props {
6+
index: number;
7+
side: SplitSide;
8+
className?: string;
9+
lineNumber: number;
10+
diffFile: DiffFile;
11+
onOpenAddWidget: (lineNumber: number, side: SplitSide) => void;
12+
onWidgetClick?: (lineNumber: number, side: SplitSide) => void;
13+
}
14+
15+
let props: Props = $props();
16+
</script>
17+
18+
<div
19+
class={'diff-add-widget-wrapper invisible select-none transition-transform hover:scale-110 group-hover:visible' +
20+
(props.className ? ' ' + props.className : '')}
21+
style={`
22+
width: calc(var(${diffFontSizeName}) * 1.4),
23+
height: calc(var(${diffFontSizeName}) * 1.4)
24+
`}
25+
>
26+
<button
27+
class="diff-add-widget z-[1] flex h-full w-full origin-center cursor-pointer items-center justify-center rounded-md text-[1.2em]"
28+
style={`
29+
color: var(${addWidgetColorName}),
30+
backgroundColor: var(${addWidgetBGName})
31+
`}
32+
onclick={() => {
33+
props.onOpenAddWidget(props.lineNumber, props.side);
34+
props.onWidgetClick?.(props.lineNumber, props.side);
35+
}}
36+
>
37+
+
38+
</button>
39+
</div>

packages/svelte/src/lib/components/DiffSplitView.svelte

Whitespace-only changes.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<script lang="ts">
2+
import {
3+
getPlainDiffTemplate,
4+
getPlainLineTemplate,
5+
type DiffLine,
6+
type File
7+
} from '@git-diff-view/core';
8+
9+
import DiffNoNewLine from './DiffNoNewLine.svelte';
10+
import {
11+
addContentHighlightBGName,
12+
delContentHighlightBGName,
13+
diffFontSizeName,
14+
getSymbol,
15+
NewLineSymbol
16+
} from '@git-diff-view/utils';
17+
18+
interface Props {
19+
rawLine: string;
20+
diffLine?: DiffLine;
21+
plainLine?: File['plainFile'][number];
22+
operator?: 'add' | 'del';
23+
enableWrap?: boolean;
24+
enableTemplate?: boolean;
25+
}
26+
27+
let props: Props = $props();
28+
29+
let isNewLineSymbolChanged = () => props.diffLine?.changes?.newLineSymbol;
30+
31+
const range = () => props.diffLine?.changes?.range;
32+
33+
const str1 = () => props.rawLine.slice(0, range()?.location);
34+
35+
const str2 = () => {
36+
const r = range();
37+
return r ? props.rawLine.slice(r.location, r.location + r.length) : '';
38+
};
39+
40+
const str3 = () => {
41+
const r = range();
42+
return r ? props.rawLine.slice(r.location + r.length) : '';
43+
};
44+
45+
const isLast = () => str2().includes('\n');
46+
47+
const _str2 = () => (isLast() ? str2().replace('\n', '').replace('\r', '') : str2);
48+
49+
const initTemplate = () => {
50+
if (props.diffLine?.changes?.hasLineChange) {
51+
if (
52+
props.enableTemplate &&
53+
props.diffLine?.plainTemplate &&
54+
typeof getPlainDiffTemplate === 'function'
55+
) {
56+
getPlainDiffTemplate({
57+
diffLine: props.diffLine,
58+
rawLine: props.rawLine,
59+
operator: props.operator || 'add'
60+
});
61+
}
62+
} else {
63+
if (props.enableTemplate && props.plainLine && !props.plainLine?.template) {
64+
props.plainLine.template = getPlainLineTemplate(props.plainLine.value);
65+
}
66+
}
67+
};
68+
69+
initTemplate();
70+
</script>
71+
72+
{#if props.diffLine?.changes?.hasLineChange}
73+
{#if props.enableTemplate && props.diffLine?.plainTemplate}
74+
<span class="diff-line-content-raw">
75+
<span data-template>
76+
{@html props.diffLine.plainTemplate}
77+
</span>
78+
{#if isNewLineSymbolChanged() === NewLineSymbol.NEWLINE}
79+
<span
80+
data-no-newline-at-end-of-file-symbol
81+
class={props.enableWrap
82+
? 'block !text-red-500'
83+
: 'inline-block align-middle !text-red-500'}
84+
style={`
85+
width: var(${diffFontSizeName}),
86+
height: var(${diffFontSizeName})
87+
`}
88+
>
89+
<DiffNoNewLine />
90+
</span>
91+
{/if}
92+
</span>
93+
{:else}
94+
<span class="diff-line-content-raw">
95+
<span
96+
data-range-start={range()?.location}
97+
data-range-end={range() ? range()!.location + range()!.length : 0}
98+
>
99+
{str1()}
100+
<span
101+
data-diff-highlight
102+
class="rounded-[0.2em]"
103+
style={`
104+
background-color:
105+
operator === "add" ? var(${addContentHighlightBGName}) : var(${delContentHighlightBGName}),
106+
`}
107+
>
108+
{#if isLast()}
109+
{_str2()}
110+
<span data-newline-symbol>{getSymbol(isNewLineSymbolChanged())}</span>
111+
{:else}
112+
{str2()}
113+
{/if}
114+
</span>
115+
{str3}
116+
</span>
117+
{#if isNewLineSymbolChanged() === NewLineSymbol.NEWLINE}
118+
<span
119+
data-no-newline-at-end-of-file-symbol
120+
class={props.enableWrap
121+
? 'block !text-red-500'
122+
: 'inline-block align-middle !text-red-500'}
123+
style={`
124+
width: var(${diffFontSizeName}),
125+
height: var(${diffFontSizeName})
126+
`}
127+
>
128+
<DiffNoNewLine />
129+
</span>
130+
{/if}
131+
</span>
132+
{/if}
133+
{:else if props.enableTemplate && props.plainLine?.template}
134+
<span class="diff-line-content-raw">
135+
<span data-template>
136+
{@html props.plainLine.template}
137+
</span>
138+
</span>
139+
{:else}
140+
<span class="diff-line-content-raw">{props.rawLine}</span>
141+
{/if}

0 commit comments

Comments
 (0)