Skip to content

Commit c15437b

Browse files
committed
feat(diff-navigation): added diff navigation to monaco diff editor
1 parent 933797a commit c15437b

File tree

4 files changed

+49
-93
lines changed

4 files changed

+49
-93
lines changed

components/v2/diffActionBar.vue

Lines changed: 29 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
<template>
22
<section
3-
class="flex items-center justify-between px-4 py-2 mb-4 sticky top-[70px] dark:bg-gray-700 bg-gray-300 dark:bg-opacity-50 bg-opacity-50 backdrop-blur-sm rounded-md shadow-lg border border-gray-500 w-full z-10"
3+
class="
4+
flex
5+
items-center
6+
justify-between
7+
px-4
8+
py-2
9+
mb-4
10+
sticky
11+
top-[70px]
12+
dark:bg-gray-700
13+
bg-gray-300
14+
dark:bg-opacity-50
15+
bg-opacity-50
16+
backdrop-blur-sm
17+
rounded-md
18+
shadow-lg
19+
border border-gray-500
20+
w-full
21+
z-10
22+
"
423
>
524
<div class="flex gap-4">
6-
<ToggleInSync />
725
<NextDiff :click-handler="goToNextDiff" />
826
<PrevDiff :click-handler="goToPreviousDiff" />
927
</div>
@@ -14,7 +32,6 @@
1432
<script lang="ts">
1533
import Vue from 'vue'
1634
import PrevDiff from '../buttons/prevDiff.vue'
17-
import ToggleInSync from '../buttons/toggleInSync.vue'
1835
import NextDiff from '../buttons/nextDiff.vue'
1936
import CopyLink from '../buttons/copyLink.vue'
2037
import { putToClipboard } from '~/helpers/utils'
@@ -23,9 +40,14 @@ export default Vue.extend({
2340
components: {
2441
PrevDiff,
2542
NextDiff,
26-
ToggleInSync,
2743
CopyLink,
2844
},
45+
props: {
46+
diffNavigator: {
47+
type: Object,
48+
required: true,
49+
},
50+
},
2951
data(): DiffActionBarData {
3052
return {
3153
copied: false,
@@ -35,37 +57,7 @@ export default Vue.extend({
3557
}
3658
},
3759
mounted() {
38-
const lhsDiffNode = document.getElementById('lhsDiff')
39-
const rhsDiffNode = document.getElementById('rhsDiff')
40-
if (lhsDiffNode && rhsDiffNode) {
41-
const isLHSBigger =
42-
lhsDiffNode.children.length > rhsDiffNode.children.length
43-
let comparator, comparer
44-
if (isLHSBigger) {
45-
comparer = lhsDiffNode
46-
comparator = rhsDiffNode
47-
} else {
48-
comparer = rhsDiffNode
49-
comparator = lhsDiffNode
50-
}
51-
this.comparator = comparator
52-
this.treeWalker = document.createTreeWalker(
53-
comparer,
54-
NodeFilter.SHOW_ELEMENT,
55-
{
56-
acceptNode: (node: Node) => {
57-
if (
58-
(node as HTMLDivElement).classList.contains('bg-red-200') ||
59-
(node as HTMLDivElement).classList.contains('bg-green-200')
60-
) {
61-
return NodeFilter.FILTER_ACCEPT
62-
}
63-
return NodeFilter.FILTER_REJECT
64-
},
65-
}
66-
)
67-
document.addEventListener('keydown', this.handleCtrlC)
68-
}
60+
document.addEventListener('keydown', this.handleCtrlC)
6961
},
7062
beforeDestroy() {
7163
document.removeEventListener('keydown', this.handleCtrlC)
@@ -96,64 +88,10 @@ export default Vue.extend({
9688
}, 5000)
9789
},
9890
goToNextDiff() {
99-
const currentNode = this.treeWalker?.currentNode
100-
const nextNode = this.treeWalker?.nextNode()
101-
if (nextNode) {
102-
const currentNodeIndex = Array.prototype.indexOf.call(
103-
currentNode?.parentElement?.children,
104-
currentNode
105-
)
106-
const nextNodeIndex = Array.prototype.indexOf.call(
107-
nextNode.parentElement?.children,
108-
nextNode
109-
)
110-
const comparatorCurrentNode =
111-
this.comparator?.children[currentNodeIndex]
112-
const comparatorNextNode = this.comparator?.children[nextNodeIndex]
113-
this.toggleDiffHunkAndScrollIntoView(
114-
[
115-
currentNode as HTMLDivElement,
116-
comparatorCurrentNode as HTMLDivElement,
117-
],
118-
[nextNode as HTMLDivElement, comparatorNextNode as HTMLDivElement]
119-
)
120-
}
91+
this.diffNavigator.next()
12192
},
12293
goToPreviousDiff() {
123-
const currentNode = this.treeWalker?.currentNode
124-
const prevNode = this.treeWalker?.previousNode()
125-
if (prevNode) {
126-
const currentNodeIndex = Array.prototype.indexOf.call(
127-
currentNode?.parentElement?.children,
128-
currentNode
129-
)
130-
const prevNodeIndex = Array.prototype.indexOf.call(
131-
prevNode.parentElement?.children,
132-
prevNode
133-
)
134-
const comparatorCurrentNode =
135-
this.comparator?.children[currentNodeIndex]
136-
const comparatorPrevNode = this.comparator?.children[prevNodeIndex]
137-
this.toggleDiffHunkAndScrollIntoView(
138-
[
139-
currentNode as HTMLDivElement,
140-
comparatorCurrentNode as HTMLDivElement,
141-
],
142-
[prevNode as HTMLDivElement, comparatorPrevNode as HTMLDivElement]
143-
)
144-
}
145-
},
146-
toggleDiffHunkAndScrollIntoView(
147-
unselectedNodes: Array<HTMLDivElement | undefined> = [],
148-
selectedNodes: Array<HTMLDivElement | undefined> = []
149-
) {
150-
unselectedNodes.forEach((element) => {
151-
element?.querySelector('p')?.classList.remove('selected')
152-
})
153-
selectedNodes.forEach((element) => {
154-
element?.querySelector('p')?.classList.add('selected')
155-
element?.scrollIntoView()
156-
})
94+
this.diffNavigator.previous()
15795
},
15896
},
15997
})

helpers/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ export interface DiffData {
3535
rhsLabel: string
3636
lhsLabel: string
3737
monacoDiffEditor: any
38+
diffNavigator: any
3839
}

pages/v2/diff.vue

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<div class="page-contents">
33
<Navbar :show-back-button="true" />
44
<main class="outline-none" tabindex="0">
5-
<DiffActionBar />
5+
<DiffActionBar :diff-navigator="diffNavigator" />
66
<section
7-
class="flex items-stretch w-full gap-4 font-mono text-gray-800 dark:text-gray-50"
7+
class="flex items-stretch w-full gap-4 font-mono text-gray-800 dark:text-gray-50"
88
>
99
<div
1010
id="monaco-diff-viewer"
@@ -32,6 +32,7 @@ export default Vue.extend({
3232
rhsLabel: '',
3333
lhsLabel: '',
3434
monacoDiffEditor: {},
35+
diffNavigator: {},
3536
}
3637
},
3738
head() {
@@ -77,6 +78,7 @@ export default Vue.extend({
7778
enabled: false,
7879
},
7980
wordWrap: 'on',
81+
contextmenu: false,
8082
}
8183
if (monacoDiffViewerEl) {
8284
this.monacoDiffEditor = monaco.editor.createDiffEditor(
@@ -90,6 +92,14 @@ export default Vue.extend({
9092
original: monaco.editor.createModel(this.lhs, 'javascript'),
9193
modified: monaco.editor.createModel(this.rhs, 'javascript'),
9294
})
95+
this.diffNavigator = monaco.editor.createDiffNavigator(
96+
this.monacoDiffEditor,
97+
{
98+
followsCaret: true,
99+
ignoreCharChanges: true,
100+
alwaysRevealFirst: true,
101+
}
102+
)
93103
}
94104
}
95105
},

vercel.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,12 @@
99
]
1010
}
1111
}
12+
],
13+
"redirects": [
14+
{
15+
"source": "/",
16+
"destination": "/v2",
17+
"permanent": false
18+
}
1219
]
1320
}

0 commit comments

Comments
 (0)