Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 51 additions & 18 deletions tools/diff-checker/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,62 @@ self.onmessage = function(e) {
let diffObj = null;
let language = 'plaintext';

// Detect Language for formatting (only if we have right side text)
if (text2 && typeof text2 === 'string') {
// Parse JSON if needed BEFORE highlighting
let rawA = text1 || '';
let rawB = text2 || '';

if (mode === 'json') {
try {
rawA = rawA ? JSON.stringify(JSON.parse(rawA), null, 4) : '';
} catch(e) {}
try {
rawB = rawB ? JSON.stringify(JSON.parse(rawB), null, 4) : '';
} catch(e) {}
}

// Detect Language for formatting
if (rawB && typeof rawB === 'string') {
try {
const detected = hljs.highlightAuto(text2.slice(0, 1000));
const detected = hljs.highlightAuto(rawB.slice(0, 1000));
language = detected.language || 'plaintext';
} catch (err) {
console.error("Worker highlight detection error", err);
}
}

// Helper to safely highlight or escape
const processCode = (code) => {
if (!code || code.trim() === '') return code || ' ';
try {
if (language !== 'plaintext') {
return hljs.highlight(code, { language }).value;
}
} catch (err) { }
// Fallback: full escape including quotes
return code.replace(/[&<>'"]/g, tag => ({
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
"'": '&#39;',
'"': '&quot;'
}[tag] || tag));
};

let hlA = processCode(rawA);
let hlB = processCode(rawB);

try {
if (mode === 'json') {
const j1 = text1 ? JSON.stringify(JSON.parse(text1), null, 4) : '';
const j2 = text2 ? JSON.stringify(JSON.parse(text2), null, 4) : '';
diffObj = Diff.diffLines(j1, j2);
}
else if (mode === 'lines') {
diffObj = ignoreSpace ? Diff.diffTrimmedLines(text1, text2) : Diff.diffLines(text1, text2);
if (mode === 'lines' || mode === 'json') {
diffObj = ignoreSpace ? Diff.diffTrimmedLines(hlA, hlB) : Diff.diffLines(hlA, hlB);
}
else if (mode === 'words') {
diffObj = ignoreSpace ? Diff.diffWords(text1, text2) : Diff.diffWordsWithSpace(text1, text2);
diffObj = ignoreSpace ? Diff.diffWords(hlA, hlB) : Diff.diffWordsWithSpace(hlA, hlB);
}
else {
diffObj = Diff.diffChars(text1, text2);
diffObj = Diff.diffChars(hlA, hlB);
}
} catch (e) {
self.postMessage({ error: e.message || 'Error generating diff' });
} catch (err) {
self.postMessage({ error: err.message || 'Error generating diff' });
return;
}

Expand All @@ -79,7 +108,8 @@ self.onmessage = function(e) {
typeClass,
numL: part.added ? '' : lineNumLeft++,
numR: part.removed ? '' : lineNumRight++,
codeHtml: cachedFormatCode(line, language)
codeHtml: line || ' '
codeHtml: formatCode(line, language)
});
});
});
Expand All @@ -94,8 +124,10 @@ self.onmessage = function(e) {
for (let i = 0; i < max; i++) {
sideRows.push({
type: (leftBuffer[i] !== undefined && rightBuffer[i] !== undefined) ? 'change' : (leftBuffer[i] !== undefined ? 'del' : 'add'),
left: leftBuffer[i] !== undefined ? cachedFormatCode(leftBuffer[i], language) : null,
right: rightBuffer[i] !== undefined ? cachedFormatCode(rightBuffer[i], language) : null
left: leftBuffer[i] !== undefined ? (leftBuffer[i] || ' ') : null,
right: rightBuffer[i] !== undefined ? (rightBuffer[i] || ' ') : null
left: leftBuffer[i] !== undefined ? formatCode(leftBuffer[i], language) : null,
right: rightBuffer[i] !== undefined ? formatCode(rightBuffer[i], language) : null
});
}
leftBuffer.length = 0;
Expand All @@ -112,7 +144,8 @@ self.onmessage = function(e) {
rightBuffer.push(...lines);
} else {
flushBuffers();
lines.forEach(l => sideRows.push({ type: 'neutral', left: cachedFormatCode(l, language), right: cachedFormatCode(l, language) }));
lines.forEach(l => sideRows.push({ type: 'neutral', left: l || ' ', right: l || ' ' }));
lines.forEach(l => sideRows.push({ type: 'neutral', left: formatCode(l, language), right: formatCode(l, language) }));
}
});
flushBuffers();
Expand Down
Loading