Skip to content

Commit 7278ba8

Browse files
authored
Merge pull request #39 from missing-elements/fix/build-page-damaged-link
The build page says a damaged link is damaged, and how to bring its source
2 parents e7c3bc1 + d5c11d1 commit 7278ba8

3 files changed

Lines changed: 62 additions & 6 deletions

File tree

‎src/assets/site.css‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,9 @@ tbody th a:hover code { text-decoration: underline; }
647647
at once for one a chat sent with the source in the link. What is said to one alone is not shown
648648
to the other; the class is on <html> before the page paints (index.njk). */
649649
.linked .when-unlinked, :root:not(.linked) .when-linked { display: none; }
650+
/* A link whose source could not be read: what is said of the source it carried gives way to what
651+
is said of the link, from when build-page.ts has tried it. */
652+
.unread .when-read, :root:not(.unread) .when-unread { display: none; }
650653

651654
/* A bar at the top, then bands the width of the window, each holding a column of the page's width. */
652655
:root {

‎src/h5p/build/build-page.ts‎

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ import { formatSource, jsonProblem, place, type Target } from './json-scan'
2626
* a sample that plays (`SAMPLE`), and finds the sample's source in the box, which the first paste
2727
* replaces whole (`prefillSample`). The markup says which words are for whom, and the class
2828
* `linked` on `<html>` shows them, set before the page paints by the script in `index.njk` and
29-
* kept in step with the address here.
29+
* kept in step with the address here. A link whose source cannot be read is said to be damaged,
30+
* with the ways to bring the source (`linkUnread`).
3031
*/
3132

3233
type Opened = Awaited<ReturnType<typeof openPack>>
@@ -41,6 +42,8 @@ const sourceField = $<HTMLTextAreaElement>('source')
4142
const sourceLabel = $('source-label')
4243
const sourceState = $('source-state')
4344
const sourceFile = $<HTMLInputElement>('source-file')
45+
const linkState = $('link-state')
46+
const openSource = $<HTMLButtonElement>('open-source')
4447
const filesStep = $('files-step')
4548
const fileList = $<HTMLUListElement>('file-list')
4649
const filesInput = $<HTMLInputElement>('files')
@@ -117,6 +120,28 @@ function setStatus(text: string, state: 'idle' | 'building' | 'ready' | 'error')
117120
status.dataset.state = state
118121
}
119122

123+
/**
124+
* A link whose source cannot be read. A chat writes the link out in its reply, and a compressed
125+
* source survives no wrong character: a link ChatGPT gave held 43 characters of its own in place
126+
* of 37, near its start, and was the command's output everywhere else. The page then said the link
127+
* had carried the source, over an empty box, with the reason under Build, out of sight in a window
128+
* 800px high. So it says the link is damaged where a person who opened it looks. The class `unread`
129+
* on `<html>` shows what the hero says of such a link in place of what it says of a source the link
130+
* carried, for the rest of the visit, since the link carried none whatever comes after. The words
131+
* above the box are the ways to bring the source, and stay until one is here (`checkSource`).
132+
*/
133+
function linkUnread(unread: boolean): void {
134+
document.documentElement.classList.toggle('unread', unread)
135+
showLinkState(unread)
136+
}
137+
138+
/** The words above the box, and with them the step's marker, which site.css draws from their state. */
139+
function showLinkState(show: boolean): void {
140+
linkState.hidden = !show
141+
if (show) linkState.dataset.state = 'error'
142+
else delete linkState.dataset.state
143+
}
144+
120145
/** Where a problem is in the source, for the button that goes there: its place in the text, or none. */
121146
function target({ path, at }: Problem): Target {
122147
return at === undefined ? { path } : { at }
@@ -316,6 +341,8 @@ player.addEventListener('error', (event) => {
316341
*/
317342
function checkSource(): void {
318343
const text = sourceField.value
344+
// A source came after a link that could not be read, from a file or a paste: the ways to bring one go.
345+
if (!linkState.hidden && compactSource(text)) showLinkState(false)
319346
const problem = jsonProblem(text)
320347
sourceState.dataset.state = problem ? 'error' : text.trim() ? 'ok' : ''
321348
if (!problem) {
@@ -406,6 +433,8 @@ sourceFile.addEventListener('change', async () => {
406433
if (!file) return
407434
setSource(await file.text())
408435
})
436+
// The same file field, from the words above the box on a link that could not be read.
437+
openSource.addEventListener('click', () => sourceFile.click())
409438

410439
// The label is for the textarea, which the editor hides: a click on it goes to the editor.
411440
sourceLabel.addEventListener('click', () => editor?.focus())
@@ -537,9 +566,12 @@ async function fromLink(): Promise<void> {
537566
try {
538567
text = await sourceFromFragment(location.hash)
539568
} catch (error) {
540-
setStatus(error instanceof Error ? error.message : String(error), 'error')
569+
// Why it cannot be read is for whoever looks into it; the person is told what to do.
570+
console.warn(error instanceof Error ? error.message : String(error))
571+
linkUnread(true)
541572
return
542573
}
574+
linkUnread(false)
543575
if (text === null) return
544576
carried = compactSource(text) ?? ''
545577
setSource(text)

‎src/h5p/build/index.njk‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ csp: "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' da
3030
(#source=), gets the build at once. One who came with none gets a landing page: what it makes,
3131
a sample that plays, how to make their own. What is said to one alone is marked when-linked or
3232
when-unlinked, and site.css shows it by the class this line puts on <html> before the page
33-
paints; build-page.ts keeps the class in step with the address from then on. -#}
33+
paints; build-page.ts keeps the class in step with the address from then on. A link whose
34+
source cannot be read is a third case, which build-page.ts finds once it has tried: it puts
35+
`unread` on <html>, and what is said of a source the link carried is marked when-read, what is
36+
said in its place when-unread. -#}
3437
<script>if (new URLSearchParams(location.hash.slice(1)).has("source")) document.documentElement.classList.add("linked")</script>
3538
{% include "topbar.njk" %}
3639

@@ -51,11 +54,20 @@ csp: "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' da
5154
<a class="button button-solid button-large" href="#make">Make your own</a>
5255
<a class="button button-large" href="#build-it">Paste your chat's JSON</a>
5356
</div>
54-
<p class="lead when-linked">The link you opened carries an activity an AI chat wrote.</p>
55-
<p class="when-linked">
57+
<p class="lead when-linked when-read">The link you opened carries an activity an AI chat wrote.</p>
58+
<p class="when-linked when-read">
5659
This page builds it in your browser, where you play it and download a
5760
<code>.h5p</code> file that Moodle or any other H5P site takes. Nothing is uploaded.
5861
</p>
62+
{#- A link whose source cannot be read: a chat writes the link out itself, and one wrong
63+
character leaves nothing of a compressed source. The page says so here, first, in place
64+
of saying the link carried an activity, and what to do above the source's box. These
65+
two stay for the visit, so they say what stays true once the source has come another way. -#}
66+
<p class="lead when-unread">The link you opened arrived damaged, so the activity in it cannot be read.</p>
67+
<p class="when-unread">
68+
This page builds an activity in your browser from its source, which
69+
<a href="#source-heading">step 1</a> says how to bring here. Nothing is uploaded.
70+
</p>
5971
</div>
6072
{#- The sample is /h5p/build/sample.h5p, which Vite builds from sample.json beside this file.
6173
build-page.ts gives the player its address only for a visitor who came with no source. -#}
@@ -157,7 +169,16 @@ csp: "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' da
157169
<section class="step" aria-labelledby="source-heading">
158170
<h3 id="source-heading"><span class="step-marker"><span class="step-number">1</span></span> Source</h3>
159171
<p class="when-unlinked">The source is your activity as the chat wrote it. The sample's is here to start with: paste yours over it, or open it from a file.</p>
160-
<p class="when-linked">The source is your activity as the chat wrote it. The link carried it here.</p>
172+
<p class="when-linked">The source is your activity as the chat wrote it. <span class="when-read">The link carried it here.</span></p>
173+
{#- Shown by build-page.ts for a link whose source cannot be read, until a source is here: above
174+
the box, where a person who opened the link looks, with each way to bring the source. -#}
175+
<p class="status" id="link-state" role="status" hidden>
176+
The source this link carried cannot be read: a chat can get characters wrong when it
177+
writes out a long link. Ask it to give the link again. If it gave you a
178+
<code>.source.json</code> file,
179+
<button type="button" class="link-button" id="open-source">open that file here</button>
180+
and choose Build below. Or ask it for the source as JSON and paste it into the box.
181+
</p>
161182
<div class="field">
162183
<label for="source" id="source-label">The source, as JSON</label>
163184
<textarea id="source" rows="12" spellcheck="false" autocomplete="off" placeholder="The source your chat wrote goes here. It starts with { and ends with }."></textarea>

0 commit comments

Comments
 (0)