Spaces:
Running on Zero
Running on Zero
Download avatar/transcript-harness.html from WolfDavid/japanese-learning-avatar: direct link, hf CLI and curl.
- Browser
- Download file 4.19 kB
-
https://huggingface.co/spaces/WolfDavid/japanese-learning-avatar/resolve/fd38c7cef051678f03510b433e58275960e449fc/avatar/transcript-harness.html
- Command line
-
hf download hf://spaces/WolfDavid/japanese-learning-avatar@fd38c7cef051678f03510b433e58275960e449fc/avatar/transcript-harness.html
-
curl -L -o transcript-harness.html https://huggingface.co/spaces/WolfDavid/japanese-learning-avatar/resolve/fd38c7cef051678f03510b433e58275960e449fc/avatar/transcript-harness.html
4.19 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>Transcript harness</title> | |
| <link rel="stylesheet" href="./transcript.css" /> | |
| <style> | |
| body { | |
| margin: 16px; | |
| font: 16px/1.4 system-ui, sans-serif; | |
| } | |
| /* Border and padding only: the column's height and overflow are transcript.css's, so | |
| the harness measures the shape the app ships rather than one of its own. */ | |
| #transcript-text { | |
| border: 1px solid #ccc; | |
| padding: 8px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- | |
| THE STANDALONE LAYER FOR THE TRANSCRIPT (plan 02-07). Open it off a static server | |
| with no Python app and no host framework: the golden fixture's token records go | |
| through avatar/transcript.js into real <ruby><rt> DOM, exactly as stage.html does | |
| for the avatar. If this page renders ruby and the | |
| deployed page does not, the fault is the host, not the renderer. | |
| window.__renderFixture(number, who) takes the 1-BASED sentence number of the 02-05 | |
| table (#9 = 日本語を勉強しています。, #13 = 田中さんは東京に住んでいます。). That is the ONE | |
| convention every prose reference and every test in 02-07 / 02-08 / 02-09 uses - | |
| never pass a 0-based index. window.__fixtureUnits(number) returns the same | |
| sentence's token records for an oracle to compute against. | |
| Query parameters: ?narrow=1 sets #transcript-text to a 300 px SCROLLING column - the | |
| phone shape plan 02-08's popover has to stay inside, and the only way the container's | |
| own scroll event (which closes the card) can fire at all. | |
| --> | |
| <div id="reading-controls" class="reading-controls"> | |
| <label for="furigana-mode">Furigana</label> | |
| <select id="furigana-mode" aria-label="Furigana mode"> | |
| <option value="always" selected>always</option> | |
| <option value="above">above my level</option> | |
| <option value="never">never</option> | |
| </select> | |
| <label for="level-select">My level</label> | |
| <select id="level-select" aria-label="JLPT level"> | |
| <option value="N5" selected>N5</option> | |
| <option value="N4">N4</option> | |
| <option value="N3">N3</option> | |
| <option value="N2">N2</option> | |
| </select> | |
| </div> | |
| <div id="transcript-text" class="transcript" aria-live="polite"></div> | |
| <script type="module"> | |
| import { createTranscript } from './transcript.js'; | |
| const params = new URLSearchParams(location.search); | |
| const container = document.getElementById('transcript-text'); | |
| if (params.get('narrow') === '1') { | |
| container.style.width = '300px'; | |
| container.style.maxHeight = '360px'; | |
| container.style.overflowY = 'auto'; | |
| } | |
| const t = createTranscript(container); | |
| t.bindPointer(); | |
| window.__transcript = t; | |
| // The same objects the renderer writes to, not copies: a test reads live numbers. | |
| window.__transcriptDebug = t.debug.furigana; | |
| window.__popoverDebug = t.debug.popover; | |
| window.__transcriptReady = false; | |
| document.getElementById('furigana-mode').addEventListener('change', (e) => { | |
| t.setMode(e.target.value); | |
| }); | |
| document.getElementById('level-select').addEventListener('change', (e) => { | |
| t.setLevel(e.target.value); | |
| }); | |
| // The static server serves the repo root; the golden fixture is one level up from avatar/. | |
| const response = await fetch('../tests/fixtures/sentences.json'); | |
| if (!response.ok) throw new Error(`golden fixture: HTTP ${response.status}`); | |
| const fixture = await response.json(); | |
| const sentences = fixture.sentences; | |
| window.__fixtures = sentences; | |
| window.__fixtureUnits = (number) => sentences[number - 1].units; | |
| window.__renderFixture = (number, who = 'avatar') => { | |
| const { text, units } = sentences[number - 1]; | |
| const { lineId } = t.addLine({ who, text }); | |
| t.setTokens(lineId, units); | |
| return lineId; | |
| }; | |
| window.__transcriptReady = true; | |
| </script> | |
| </body> | |
| </html> | |