Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/gentle-pans-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@hyperbook/markdown": patch
"hyperbook": patch
"hyperbook-studio": patch
---

Inline the script that loads the light and dark stylesheets. It was a file, and
nothing can paint before the stylesheets it writes are there, so every first
paint waited for a round trip to fetch 1.5 kB and then another for the
stylesheets themselves. It is part of the page now, which measured about 140 ms
off the first contentful paint of the documentation on a throttled connection.
20 changes: 20 additions & 0 deletions .changeset/khaki-moles-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@hyperbook/types": minor
"@hyperbook/fs": minor
"@hyperbook/markdown": minor
"hyperbook": minor
"hyperbook-studio": minor
---

Order pages and sections together by `index`. Pages were always rendered before
the sections of the same level, so a page could not sit after or between them.
The `index` of a page and the `index` of a section are now one order, and a
section that ends up between two pages is rendered between them.

The reading order follows the navigation, so the previous and next buttons, the
breadcrumb and `::pagelist` agree with the sidebar.

A page or a section without an `index` keeps its old place: pages come before
sections, and a page wins a tie against a section. A book that gives its
sections an `index` but leaves it off a page will see that page move behind
those sections. Give the page an `index` to place it.
10 changes: 10 additions & 0 deletions .changeset/olive-moons-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@hyperbook/markdown": patch
"hyperbook": patch
"hyperbook-studio": patch
---

Fix the drawers flashing over the page while it loads. A custom element renders
its children until it is upgraded, and a side drawer is only hidden by its
shadow root, so the search drawer and the table of contents drawer painted over
the header and the article until `side-drawer.js` had run.
10 changes: 10 additions & 0 deletions .changeset/quiet-jokes-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@hyperbook/markdown": patch
"hyperbook": patch
"hyperbook-studio": patch
---

Order the pages and the subsections of a section together too. Only the top
level of the navigation shared one order, so inside a section a subsection was
still rendered after every page of that section, and the sidebar disagreed with
the previous and next buttons, which already followed the index.
11 changes: 11 additions & 0 deletions .changeset/spotty-jars-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@hyperbook/markdown": patch
"hyperbook": patch
"hyperbook-studio": patch
---

Indent the pages of a section in the navigation. They sat one pixel to the
right of a page of the level above, so only a hairline told the two levels
apart. That was harmless while every page came before every section, but a page
can sit after a section now, and it has to be readable as a page of the level
above.
21 changes: 15 additions & 6 deletions packages/fs/src/hyperbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
HyperbookSection,
Navigation,
PageNavigation,
sortNavigation,
} from "@hyperbook/types";
import { findUp } from "find-up";
import { vfile } from ".";
Expand Down Expand Up @@ -254,17 +255,25 @@ export const getPageList = (
sections: HyperbookSection[],
pages: HyperbookPage[],
): HyperbookPage[] => {
let pageList = [...pages];
let pageList: HyperbookPage[] = [];

for (const section of sections) {
// Reading order follows the navigation, so the previous and next buttons
// agree with the sidebar when a section sits between two pages.
for (const entry of sortNavigation(pages, sections)) {
if (entry.type === "page") {
pageList.push(entry.page);
continue;
}

const section = entry.section;
// Check if section is virtual or not
const isVirtual = section.virtual || section.navigation === "virtual";

if (!isVirtual && section.href) {
// For non-virtual sections with an href, add the index page first
const indexPage = section.pages.find(p => p.href === section.href);
const otherPages = section.pages.filter(p => p.href !== section.href);
const indexPage = section.pages.find((p) => p.href === section.href);
const otherPages = section.pages.filter((p) => p.href !== section.href);

if (indexPage) {
pageList.push(indexPage);
}
Expand Down
11 changes: 11 additions & 0 deletions packages/markdown/assets/shell.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ side-drawer {
display: none;
}

/* A custom element renders its children until it is upgraded. The drawers are
only hidden by their shadow root, so without this their content paints over
the page until side-drawer.js has run. */
side-drawer:not(:defined) {
display: none;
}

/* Hide mobile nav toggle when JavaScript is disabled */
.no-js .mobile-nav .toggle {
display: none;
Expand Down Expand Up @@ -662,6 +669,7 @@ nav li + li {

.section {
margin-top: 4px;
margin-bottom: 4px;
}

.section summary.name {
Expand Down Expand Up @@ -733,6 +741,9 @@ nav li + li {
.section > .links {
border-left-width: 1px;
border-left-style: solid;
/* The pages of a section have to read as belonging to it, now that a page of
the level above can follow them. */
padding-left: 0.75rem;
}

.pages {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
/**
* Copyright 2024 Google LLC
* Writes the light and dark stylesheets into the page, honoring a mode the
* reader picked before. The stylesheets sit in a noscript element, so they are
* only text until this runs.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* This is inlined into the head instead of being loaded as a file. Nothing can
* paint before the stylesheets are there, so an external script would put a
* round trip in front of every first paint, and a second one in front of the
* stylesheets it writes.
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* © 2024 Google LLC. Licensed under the Apache License, Version 2.0.
* https://www.apache.org/licenses/LICENSE-2.0
*/

export const darkModeStylesheetsLoader = `
// @license © 2024 Google LLC. Licensed under the Apache License, Version 2.0.
(() => {
const ELEMENT_ID = 'dark-mode-toggle-stylesheets';
Expand All @@ -28,8 +26,8 @@
mode = localStorage.getItem(STORAGE_NAME);
} catch (e) {}

const lightCSSMediaRegex = /\(\s*prefers-color-scheme\s*:\s*light\s*\)/gi;
const darkCSSMediaRegex = /\(\s*prefers-color-scheme\s*:\s*dark\s*\)/gi;
const lightCSSMediaRegex = /\\(\\s*prefers-color-scheme\\s*:\\s*light\\s*\\)/gi;
const darkCSSMediaRegex = /\\(\\s*prefers-color-scheme\\s*:\\s*dark\\s*\\)/gi;

switch (mode) {
case LIGHT:
Expand All @@ -47,3 +45,4 @@

document.write(stylesheets);
})();
// @license-end`;
15 changes: 8 additions & 7 deletions packages/markdown/src/rehypeHtmlStructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { HyperbookContext } from "@hyperbook/types";
import { ElementContent, Root } from "hast";
import { VFile } from "vfile";
import { darkModeStylesheetsLoader } from "./darkModeStylesheetsLoader";

function parseFont(font: string): [string, string] {
const parts = font.split(":");
Expand Down Expand Up @@ -379,13 +380,13 @@ window.hyperbook.emoji = { style: "twemoji", base: "${makeUrl(["emoji"], "assets
{
type: "element",
tagName: "script",
properties: {
src: makeUrl(
["dark-mode-toggle-stylesheets-loader.js"],
"assets",
),
},
children: [],
properties: {},
children: [
{
type: "raw",
value: darkModeStylesheetsLoader,
},
],
},
{
type: "element",
Expand Down
Loading