Better md example & hide deleted text

This commit is contained in:
Andras Schmelczer 2026-10-28 23:20:17 +00:00
commit 5eac6bb012
3 changed files with 108 additions and 53 deletions

View file

@ -99,7 +99,11 @@
<main> <main>
<section class="tokenizer-selector"> <section class="tokenizer-selector">
<div class="radio-group" role="radiogroup" aria-label="Tokenization strategy"> <div
class="radio-group"
role="radiogroup"
aria-label="Tokenization strategy"
>
<label class="radio-option"> <label class="radio-option">
<input <input
type="radio" type="radio"
@ -137,7 +141,7 @@
<span class="radio-custom" aria-hidden="true"></span> <span class="radio-custom" aria-hidden="true"></span>
<div class="radio-content"> <div class="radio-content">
<span class="radio-label">Markdown</span> <span class="radio-label">Markdown</span>
<span class="radio-description">Preserve formatting</span> <span class="radio-description">Keep Markdown markers with words</span>
</div> </div>
</label> </label>
</div> </div>
@ -175,6 +179,7 @@
</div> </div>
<div class="text-area-card diamond-result"> <div class="text-area-card diamond-result">
<div class="result-header">
<label <label
id="merged-label" id="merged-label"
title="The automatically merged result - edit the boxes above to see changes in real-time." title="The automatically merged result - edit the boxes above to see changes in real-time."
@ -200,6 +205,11 @@
<path d="M3 3l18 18"></path> <path d="M3 3l18 18"></path>
</svg> </svg>
</label> </label>
<label class="history-toggle" for="show-deletions">
<input type="checkbox" id="show-deletions" aria-controls="merged" />
Show deleted text
</label>
</div>
<div <div
id="merged" id="merged"
role="textbox" role="textbox"

View file

@ -6,16 +6,27 @@ const originalTextArea = document.getElementById('original') as HTMLTextAreaElem
const leftTextArea = document.getElementById('left') as HTMLTextAreaElement; const leftTextArea = document.getElementById('left') as HTMLTextAreaElement;
const rightTextArea = document.getElementById('right') as HTMLTextAreaElement; const rightTextArea = document.getElementById('right') as HTMLTextAreaElement;
const mergedTextArea = document.getElementById('merged') as HTMLDivElement; const mergedTextArea = document.getElementById('merged') as HTMLDivElement;
const showDeletions = document.getElementById('show-deletions') as HTMLInputElement;
const tokenizerRadios = document.querySelectorAll( const tokenizerRadios = document.querySelectorAll(
'input[name="tokenizer"]' 'input[name="tokenizer"]'
) as NodeListOf<HTMLInputElement>; ) as NodeListOf<HTMLInputElement>;
const sampleText = `The reconcile-text library is embedded on this page as a WASM module and powers these text boxes. Experiment with changing the "Original", "First user's edit", and "Second user's edit" text boxes to see competing changes get merged in real-time within the "Merged result" box. const sampleText = `## Draft release
## Release plan
Here, you will see color-coded tokens marking the origin of each token, including ones that got deleted. The result depends on the tokenisation strategy selected above: Build steps:
- Character-based - Prototype
- Word-based (default) - Publish
- Markdown-based`;
Review checklist:
- [ ] Draft
- [ ] Review
Announcement:
> Internal
> Ready
Use color-coded changes to compare tokenisers.`;
let pendingUpdate: number | null = null; let pendingUpdate: number | null = null;
function scheduleUpdate(): void { function scheduleUpdate(): void {
@ -31,6 +42,9 @@ async function main(): Promise<void> {
originalTextArea.addEventListener('input', scheduleUpdate); originalTextArea.addEventListener('input', scheduleUpdate);
leftTextArea.addEventListener('input', scheduleUpdate); leftTextArea.addEventListener('input', scheduleUpdate);
rightTextArea.addEventListener('input', scheduleUpdate); rightTextArea.addEventListener('input', scheduleUpdate);
showDeletions.addEventListener('change', () => {
mergedTextArea.classList.toggle('show-deletions', showDeletions.checked);
});
document.addEventListener('selectionchange', () => { document.addEventListener('selectionchange', () => {
if ( if (
@ -51,15 +65,21 @@ async function main(): Promise<void> {
updateMergedText(); updateMergedText();
} }
// Edit the instructions to generate example edits // Deleting obsolete lines while reformatting their neighbours leaves orphaned
// markers with Word, but Markdown keeps each marker attached to its line's first word.
function loadSample(): void { function loadSample(): void {
originalTextArea.value = sampleText; originalTextArea.value = sampleText;
leftTextArea.value = leftTextArea.value = sampleText
sampleText.replace('color', 'colour') + .replace('## Draft release\n', '')
"\n\nCheck out what's the most complex conflict you can come up with!"; .replace('- Prototype\n', '')
.replace('- [ ] Draft\n', '')
.replace('> Internal\n', '')
.replace('color', 'colour');
rightTextArea.value = sampleText rightTextArea.value = sampleText
.replace('Experiment with changing', 'Try editing') .replace('## Release plan', '# Release plan')
.replace('WASM', 'WebAssembly'); .replace('- Publish', '1. Publish')
.replace('- [ ] Review', '- [x] Review')
.replace('> Ready', 'Ready');
} }
function updateMergedText(): void { function updateMergedText(): void {

View file

@ -234,6 +234,20 @@ main {
align-items: center; align-items: center;
} }
.result-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 8px 16px;
}
.history-toggle {
gap: 6px;
font-size: 0.85rem;
cursor: pointer;
}
.diamond-result svg { .diamond-result svg {
width: 20px; width: 20px;
height: 20px; height: 20px;
@ -277,7 +291,8 @@ textarea {
resize: none; resize: none;
outline: none; outline: none;
margin-bottom: 0; margin-bottom: 0;
field-sizing: content; /* Doesn't work in Safari yet */ field-sizing: content;
/* Doesn't work in Safari yet */
} }
#merged { #merged {
@ -288,6 +303,14 @@ textarea {
position: relative; position: relative;
white-space: pre-wrap; white-space: pre-wrap;
} }
&:not(.show-deletions) {
.RemovedFromLeft,
.RemovedFromRight {
display: none;
}
}
} }
.Unchanged { .Unchanged {
@ -409,10 +432,12 @@ $DOT_RADIUS: 4;
} }
@keyframes blink-stick { @keyframes blink-stick {
0%, 0%,
100% { 100% {
opacity: 1; opacity: 1;
} }
50% { 50% {
opacity: 0; opacity: 0;
} }