Better md example & hide deleted text
This commit is contained in:
parent
3894e7e401
commit
5eac6bb012
3 changed files with 108 additions and 53 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue