P44 OCR Viewer — Remove diff system, add Pass 2 split panel view
Scope: p44-ocr-viewer.js, p44-ocr-viewer.css, p44-ocr-viewer.html. Complete removal of all diff logic, replace with a simple toggleable split panel for Pass 2.
PART 1 — Remove diff entirely
HTML — remove these elements:
wrapper — move its children (#line-numbers and #text-editor) back up directly inside #editor-wrap
CSS — remove all rules for:
#diff-toolbar
#diff-toolbar .diff-legend
#diff-toolbar .diff-count
.diff-swatch
.diff-swatch-del
.diff-swatch-ins
.diff-del
.diff-ins
#diff-reference
#diff-reference-label
#editor-bottom
JS — remove these functions entirely:
buildInlineDiff()
renderInlineDiff()
showDiffToolbar()
applyDiffToDisplay()
applyDiffToReference()
toggleDiff()
JS — remove these DOM refs:
const btnDiff
const diffToolbar
const diffReference
const editorBottom
JS — remove state.diffMode from the state object.
JS — in showOCRPage() remove the entire block added for diff auto-enable and toolbar display — the block starting with const corrForPage = state.corrections && state.corrections[pageNum] down to the closing } of the Pass 2 auto-diff block. Restore the original Pass 2 block at the bottom of showOCRPage():
javascript if (currentRole === 'pass2') {
if (!state.editMode) enterEditMode();
updatePass2NavButtons();
}
JS — in enterEditMode() remove the line applyDiffToReference(pageNum);
JS — in exitEditMode() remove:
diffReference.style.display = 'none';
if (state.diffMode) applyDiffToDisplay(pageNum);
JS — in goToPage() remove the four lines:
javascript state.diffMode = false;
btnDiff.classList.remove('active');
diffToolbar.style.display = 'none';
diffReference.style.display = 'none';
PART 2 — HTML (p44-ocr-viewer.html)
In the right panel header, add a toggle button immediately before #btn-edit:
html
Inside #text-panel-body, immediately before #text-output, add the original OCR reference pane:
html
ORIGINAL OCR
PART 3 — CSS (p44-ocr-viewer.css)
Add at the end of the file:
css/* ── Split panel layout ───────────────────────────────────────── */
#text-panel-body {
display: flex;
flex-direction: column;
overflow: hidden;
}
#split-pane {
display: none;
flex-direction: column;
flex: 1;
min-height: 0;
overflow: hidden;
}
#split-pane-header {
font-size: 9px;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--gold-dim);
padding: 5px 16px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
background: var(--surface);
}
#split-ocr-wrap {
display: flex;
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 12px 0;
}
#split-line-numbers {
width: 48px;
flex-shrink: 0;
padding: 0 8px 0 12px;
text-align: right;
font-size: 11px;
line-height: 1.75;
color: var(--gold-dim);
font-family: 'Courier New', monospace;
user-select: none;
border-right: 1px solid var(--border);
margin-right: 12px;
}
#split-ocr-output {
flex: 1;
min-width: 0;
font-size: 12.5px;
line-height: 1.75;
color: var(--text);
white-space: pre-wrap;
font-family: 'Georgia', 'Times New Roman', serif;
padding-right: 16px;
}
#split-divider {
height: 4px;
background: var(--border);
flex-shrink: 0;
cursor: row-resize;
border-top: 1px solid var(--gold-dim);
border-bottom: 1px solid var(--gold-dim);
}
/* When split is active, text-output and editor-wrap each take half */
#text-panel-body.split-active #text-output,
#text-panel-body.split-active #editor-wrap {
flex: 1;
min-height: 0;
overflow-y: auto;
}
#text-panel-body.split-active {
display: flex;
flex-direction: column;
}
PART 4 — JS (p44-ocr-viewer.js)
4a — DOM refs
Add:
javascriptconst btnSplit = document.getElementById('btn-split');
const splitPane = document.getElementById('split-pane');
const splitDivider = document.getElementById('split-divider');
const splitOcrOutput = document.getElementById('split-ocr-output');
const splitLineNums = document.getElementById('split-line-numbers');
4b — State flag
Add to the state object:
javascriptsplitMode: false,
4c — Line number generator for split pane
Add this new function above showOCRPage():
javascriptfunction buildSplitLineNumbers(text) {
const lines = (text || '').split('\n');
return lines.map((_, i) => i + 1).join('\n');
}
4d — showSplitPane(pageNum)
Add this new function:
javascriptfunction showSplitPane(pageNum) {
const corr = state.corrections && state.corrections[pageNum];
const originalText = (corr && corr.original) || state.ocrPages[pageNum] || '';
splitOcrOutput.textContent = originalText;
splitLineNums.textContent = buildSplitLineNumbers(originalText);
splitPane.style.display = 'flex';
splitDivider.style.display = 'block';
textPanelBody.classList.add('split-active');
}
4e — hideSplitPane()
Add this new function:
javascriptfunction hideSplitPane() {
splitPane.style.display = 'none';
splitDivider.style.display = 'none';
textPanelBody.classList.remove('split-active');
}
4f — toggleSplit()
Add this new function:
javascriptfunction toggleSplit() {
state.splitMode = !state.splitMode;
btnSplit.classList.toggle('active', state.splitMode);
if (state.splitMode) {
showSplitPane(state.currentPage);
} else {
hideSplitPane();
}
}
Add the event listener immediately after:
javascriptbtnSplit.addEventListener('click', toggleSplit);
4g — applyRole()
In applyRole(), in the pass2 branch add:
javascript btnSplit.style.display = 'inline-block';
In the pass1 branch add:
javascript btnSplit.style.display = 'none';
state.splitMode = false;
hideSplitPane();
4h — goToPage()
At the start of goToPage(), after if (state.editMode) exitEditMode();, add:
javascript if (state.splitMode) showSplitPane(n);
This refreshes the split pane content for the new page without toggling it off.
4i — showOCRPage()
At the end of showOCRPage(), after updatePass2NavButtons(), add:
javascript if (state.splitMode) showSplitPane(pageNum);
VERIFICATION CHECKLIST:
Pass 1 role: Split button not visible
Pass 2 role: Split button visible in panel header
Clicking Split in Pass 2: right panel splits into original OCR on top and editor on bottom, both with line numbers, both scroll independently
Clicking Split again: collapses back to single panel, editor fills full height
Navigating to a new page while split is on: both panes update to the new page's content, split stays on
Switching from Pass 2 to Pass 1 while split is on: split closes, button hides
Original OCR pane shows raw unedited text — not the Pass 1 corrected version
Line numbers visible in both panes and match the text lines