@loadbare/app 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hub/lb-hub.browser.js +11 -0
- package/docs/reference/chrome.md +34 -2
- package/docs/tutorials/000-getting-started.md +10 -1
- package/docs/tutorials/010-pages-and-navigation.md +2 -1
- package/docs/tutorials/020-css.md +2 -1
- package/docs/tutorials/030-html-decomposition.md +2 -1
- package/package.json +1 -1
|
@@ -229,6 +229,7 @@ class LbHub extends HTMLElement {
|
|
|
229
229
|
if (!(template instanceof HTMLTemplateElement)) {
|
|
230
230
|
console.error(`lb-hub: no page host for '${page}'`);
|
|
231
231
|
this.reportUnknownPage(page);
|
|
232
|
+
this.reveal();
|
|
232
233
|
return;
|
|
233
234
|
}
|
|
234
235
|
this.page = page;
|
|
@@ -236,6 +237,7 @@ class LbHub extends HTMLElement {
|
|
|
236
237
|
// template is already in the document, so holding it back behind a
|
|
237
238
|
// network round trip only leaves <main> empty for no reason.
|
|
238
239
|
this.main.replaceChildren(template.content.cloneNode(true));
|
|
240
|
+
this.reveal();
|
|
239
241
|
let data = {};
|
|
240
242
|
try {
|
|
241
243
|
data = await fetchData(`${LB_DATA_ENDPOINT}?page=${encodeURIComponent(page)}`);
|
|
@@ -245,6 +247,15 @@ class LbHub extends HTMLElement {
|
|
|
245
247
|
}
|
|
246
248
|
applyData(this, data);
|
|
247
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* An app that ships `<body hidden>` (see docs/reference/chrome.md) is
|
|
252
|
+
* asking to stay invisible until there is something coherent to show,
|
|
253
|
+
* rather than flash the chrome before `<main>` has real content. This is
|
|
254
|
+
* a no-op for an app that doesn't use that convention.
|
|
255
|
+
*/
|
|
256
|
+
reveal() {
|
|
257
|
+
document.body.hidden = false;
|
|
258
|
+
}
|
|
248
259
|
/**
|
|
249
260
|
* A path that resolves to no page host is discovered client-side, after a
|
|
250
261
|
* successful 200 — every route gets the same document, so there is no
|
package/docs/reference/chrome.md
CHANGED
|
@@ -20,8 +20,9 @@ Here is a minimal but fully complaint chrome for a typical app:
|
|
|
20
20
|
<title>Membership Roster</title>
|
|
21
21
|
<script src="/client.js" defer></script>
|
|
22
22
|
<link rel="stylesheet" href="/app.css" />
|
|
23
|
+
<noscript><style>body[hidden] { display: block; }</style></noscript>
|
|
23
24
|
</head>
|
|
24
|
-
<body>
|
|
25
|
+
<body hidden>
|
|
25
26
|
<lb-hub>
|
|
26
27
|
<header><h1>Membership Roster</h1></header>
|
|
27
28
|
<nav>
|
|
@@ -58,6 +59,7 @@ Everything else is optional:
|
|
|
58
59
|
| `<a lb-nav-link>` | Navigation between pages |
|
|
59
60
|
| `<dialog lb-unknown-page>` | A message when a URL matches no page |
|
|
60
61
|
| Custom elements | The chrome, decomposed into widget files |
|
|
62
|
+
| `<body hidden>` + a `<noscript>` fallback | Avoids a first-load blink — see below |
|
|
61
63
|
| Any other HTML | Header, footer, skip links, meta tags, etc. |
|
|
62
64
|
|
|
63
65
|
## Rules for writing chrome
|
|
@@ -72,4 +74,34 @@ landing page is the one named `index.page.html`. An anchor without
|
|
|
72
74
|
`lb-nav-link` is left alone and behaves like any other link.
|
|
73
75
|
|
|
74
76
|
The `lb-unknown-page` attribute, if used, must appear on a `<dialog>`.
|
|
75
|
-
Inside it, `lb-cell="page"` shows the name of the page that was asked for.
|
|
77
|
+
Inside it, `lb-cell="page"` shows the name of the page that was asked for.
|
|
78
|
+
|
|
79
|
+
## Preventing the first-load blink
|
|
80
|
+
|
|
81
|
+
`client.js` loads with `defer`, so the browser can — and typically does —
|
|
82
|
+
paint the document before the script has run. Without help, that means a
|
|
83
|
+
visible flash: the chrome appears first, then `<main>`'s real content pops in
|
|
84
|
+
a moment later and shifts everything around it.
|
|
85
|
+
|
|
86
|
+
`<body hidden>` avoids this by hiding the whole document, not just `<main>`,
|
|
87
|
+
until the hub has something to show. `<lb-hub>` un-hides `<body>` itself the
|
|
88
|
+
first time `navigate()` finishes, so the chrome and the first page's content
|
|
89
|
+
always appear together, already in their final layout — there is no
|
|
90
|
+
intermediate state to flash.
|
|
91
|
+
|
|
92
|
+
Hiding `<main>` alone doesn't work: an empty `<main>` already renders at zero
|
|
93
|
+
height, so hiding it changes nothing visible. The pop-in comes from the
|
|
94
|
+
chrome being shown *before* `<main>` has real content, not from `<main>`
|
|
95
|
+
being visibly empty — so it's the whole document that needs to wait, not
|
|
96
|
+
just the piece that was empty.
|
|
97
|
+
|
|
98
|
+
The `<noscript>` block is the escape hatch for a visitor with JavaScript
|
|
99
|
+
disabled. `<lb-hub>` is what removes `hidden` from `<body>`, so a browser
|
|
100
|
+
that never runs `client.js` would otherwise be stuck looking at a
|
|
101
|
+
permanently blank page. `<noscript>` content is only rendered when scripting
|
|
102
|
+
is off, so the fallback rule only ever applies in exactly that case — it
|
|
103
|
+
never runs, and never races with the hub, on a normal visit.
|
|
104
|
+
|
|
105
|
+
Both are optional. An app that doesn't mind the blink, or has no chrome
|
|
106
|
+
complex enough for it to be noticeable, can leave `<body>` unhidden and skip
|
|
107
|
+
the `<noscript>` block entirely.
|
|
@@ -26,8 +26,9 @@ At minimum, the chrome must contain:
|
|
|
26
26
|
<meta charset="utf-8" />
|
|
27
27
|
<title>@Loadbare/app Tutorials</title>
|
|
28
28
|
<script src="/client.js" defer></script>
|
|
29
|
+
<noscript><style>body[hidden] { display: block; }</style></noscript>
|
|
29
30
|
</head>
|
|
30
|
-
<body>
|
|
31
|
+
<body hidden>
|
|
31
32
|
<lb-hub>
|
|
32
33
|
<main></main>
|
|
33
34
|
</lb-hub>
|
|
@@ -41,6 +42,14 @@ the custom elements used anywhere in `src/`. In this basic starting point,
|
|
|
41
42
|
we have `<lb-hub>` as the only custom element, so `client.js` will just
|
|
42
43
|
contain the Javascript class `LbHub`.
|
|
43
44
|
|
|
45
|
+
`<body hidden>` and the `<noscript>` rule next to it are optional, not part
|
|
46
|
+
of the minimum above. `<lb-hub>` removes `hidden` from `<body>` as soon as it
|
|
47
|
+
has something to show, so the document stays invisible for a moment rather
|
|
48
|
+
than flashing an empty page and then popping in real content — see
|
|
49
|
+
[chrome.html](../reference/chrome.md#preventing-the-first-load-blink) for
|
|
50
|
+
why. Every chrome in the rest of these tutorials carries this forward; drop
|
|
51
|
+
it if you'd rather not have it.
|
|
52
|
+
|
|
44
53
|
## The dev script
|
|
45
54
|
|
|
46
55
|
Add a command to package.json that builds the app.
|
|
@@ -46,8 +46,9 @@ display something to the user if they type a URL that has no matching page.
|
|
|
46
46
|
<meta charset="utf-8" />
|
|
47
47
|
<title>Pages and Navigation</title>
|
|
48
48
|
<script src="/client.js" defer></script>
|
|
49
|
+
<noscript><style>body[hidden] { display: block; }</style></noscript>
|
|
49
50
|
</head>
|
|
50
|
-
<body>
|
|
51
|
+
<body hidden>
|
|
51
52
|
<lb-hub>
|
|
52
53
|
<nav>
|
|
53
54
|
<!-- a bare link to "/" goes to page "index" -->
|
|
@@ -60,8 +60,9 @@ Add the stylesheet link to the chrome:
|
|
|
60
60
|
<script src="/client.js" defer></script>
|
|
61
61
|
<!-- Add a standard stylesheet link -->
|
|
62
62
|
<link rel="stylesheet" href="/app.css" />
|
|
63
|
+
<noscript><style>body[hidden] { display: block; }</style></noscript>
|
|
63
64
|
</head>
|
|
64
|
-
<body>
|
|
65
|
+
<body hidden>
|
|
65
66
|
<lb-hub>
|
|
66
67
|
<nav>
|
|
67
68
|
<a href="/" lb-nav-link>Home</a>
|
|
@@ -27,8 +27,9 @@ element, not yet defined:
|
|
|
27
27
|
<title>Pages and Navigation</title>
|
|
28
28
|
<script src="/client.js" defer></script>
|
|
29
29
|
<link rel="stylesheet" href="/app.css" />
|
|
30
|
+
<noscript><style>body[hidden] { display: block; }</style></noscript>
|
|
30
31
|
</head>
|
|
31
|
-
<body>
|
|
32
|
+
<body hidden>
|
|
32
33
|
<lb-hub>
|
|
33
34
|
<!-- replace this from the previous tutorial...
|
|
34
35
|
<nav>
|