-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
130 lines (111 loc) · 4.64 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
document.addEventListener('DOMContentLoaded', () => {
const compareButton = document.querySelector('.js-compare-button');
const resultContainer = document.querySelector('.js-result-container');
const textInputs = document.querySelectorAll('.js-text-input');
const additionsCount = document.querySelector('.js-additions-count');
const deletionsCount = document.querySelector('.js-deletions-count');
compareButton.addEventListener('click', () => {
const text1 = textInputs[0].value;
const text2 = textInputs[1].value;
const diff = simpleDiff(text1, text2);
displayDiff(diff);
updateChangeCounts(diff);
});
function simpleDiff(text1, text2) {
const lines1 = text1.split('\n');
const lines2 = text2.split('\n');
const lcs = longestCommonSubsequence(lines1, lines2);
const diff = [];
let i = 0, j = 0, k = 0;
while (i < lines1.length || j < lines2.length) {
if (k < lcs.length && lines1[i] === lcs[k] && lines2[j] === lcs[k]) {
diff.push({ type: 'unchanged', left: lines1[i], right: lines2[j] });
i++; j++; k++;
} else if (j < lines2.length && (k === lcs.length || lines2[j] !== lcs[k])) {
diff.push({ type: 'added', left: null, right: lines2[j] });
j++;
} else if (i < lines1.length && (k === lcs.length || lines1[i] !== lcs[k])) {
diff.push({ type: 'removed', left: lines1[i], right: null });
i++;
}
}
return diff;
}
function longestCommonSubsequence(seq1, seq2) {
const m = seq1.length;
const n = seq2.length;
const dp = Array(m + 1).fill().map(() => Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (seq1[i - 1] === seq2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
const lcs = [];
let i = m, j = n;
while (i > 0 && j > 0) {
if (seq1[i - 1] === seq2[j - 1]) {
lcs.unshift(seq1[i - 1]);
i--; j--;
} else if (dp[i - 1][j] > dp[i][j - 1]) {
i--;
} else {
j--;
}
}
return lcs;
}
function displayDiff(diff) {
resultContainer.innerHTML = '';
const leftColumn = document.createElement('div');
const rightColumn = document.createElement('div');
leftColumn.className = 'diff-column left-column';
rightColumn.className = 'diff-column right-column';
let leftLineNumber = 1;
let rightLineNumber = 1;
diff.forEach(line => {
const leftLine = document.createElement('div');
const rightLine = document.createElement('div');
leftLine.className = 'diff-line';
rightLine.className = 'diff-line';
if (line.left !== null) {
leftLine.innerHTML = `<span class="line-number">${leftLineNumber}</span>${escapeHtml(line.left)}`;
leftLineNumber++;
} else {
leftLine.innerHTML = '<span class="line-number"></span>';
}
if (line.right !== null) {
rightLine.innerHTML = `<span class="line-number">${rightLineNumber}</span>${escapeHtml(line.right)}`;
rightLineNumber++;
} else {
rightLine.innerHTML = '<span class="line-number"></span>';
}
if (line.type === 'added') {
rightLine.classList.add('added');
} else if (line.type === 'removed') {
leftLine.classList.add('removed');
}
leftColumn.appendChild(leftLine);
rightColumn.appendChild(rightLine);
});
resultContainer.appendChild(leftColumn);
resultContainer.appendChild(rightColumn);
}
function updateChangeCounts(diff) {
const additions = diff.filter(line => line.type === 'added').length;
const deletions = diff.filter(line => line.type === 'removed').length;
additionsCount.textContent = `${additions} addition${additions !== 1 ? 's' : ''}`;
deletionsCount.textContent = `${deletions} deletion${deletions !== 1 ? 's' : ''}`;
}
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
});