Skip to content

Commit

Permalink
rewrite header
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Mar 16, 2024
1 parent 4721feb commit bbfc152
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
2 changes: 1 addition & 1 deletion observablehq.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default {
</svg>
</a>
<div style="display: flex; flex-grow: 1; justify-content: space-between; align-items: baseline;">
<a href="https://observablehq.com/framework/">
<a href="/">
<span class="hide-if-small">Observable</span> Framework
</a>
<span style="display: flex; align-items: baseline; gap: 0.5rem; font-size: 14px;">
Expand Down
46 changes: 39 additions & 7 deletions src/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type {DOMWindow} from "jsdom";
import {JSDOM, VirtualConsole} from "jsdom";
import {isAssetPath, relativePath, resolveLocalPath} from "./path.js";

const ASSET_PROPERTIES: readonly [selector: string, src: string][] = [
const ASSET_ATTRIBUTES: readonly [selector: string, src: string][] = [
["a[href][download]", "href"],
["audio source[src]", "src"],
["audio[src]", "src"],
Expand All @@ -17,6 +17,18 @@ const ASSET_PROPERTIES: readonly [selector: string, src: string][] = [
["video[src]", "src"]
];

const PATH_ATTRIBUTES: readonly [selector: string, src: string][] = [
["a[href]", "href"],
["audio source[src]", "src"],
["audio[src]", "src"],
["img[src]", "src"],
["img[srcset]", "srcset"],
["link[href]", "href"],
["picture source[srcset]", "srcset"],
["video source[src]", "src"],
["video[src]", "src"]
];

export function isJavaScript({type}: HTMLScriptElement): boolean {
if (!type) return true;
type = type.toLowerCase();
Expand Down Expand Up @@ -48,7 +60,7 @@ export function findAssets(html: string, path: string): Assets {
files.add(relativePath(path, localPath));
};

for (const [selector, src] of ASSET_PROPERTIES) {
for (const [selector, src] of ASSET_ATTRIBUTES) {
for (const element of document.querySelectorAll(selector)) {
const source = decodeURI(element.getAttribute(src)!);
if (src === "srcset") {
Expand Down Expand Up @@ -85,19 +97,39 @@ export function findAssets(html: string, path: string): Assets {
return {files, localImports, globalImports, staticImports};
}

interface HtmlResolvers {
resolveFile?: (specifier: string) => string;
resolveScript?: (specifier: string) => string;
export function reresolveHtmlPaths(html: string, path: string): string {
const {document} = parseHtml(html);

const resolvePath = (specifier: string): string => {
return isAssetPath(specifier) ? relativePath(path, specifier) : specifier;
};

for (const [selector, src] of PATH_ATTRIBUTES) {
for (const element of document.querySelectorAll(selector)) {
const source = decodeURI(element.getAttribute(src)!);
element.setAttribute(src, src === "srcset" ? resolveSrcset(source, resolvePath) : resolvePath(source));
}
}

return document.body.innerHTML;
}

export interface HtmlResolvers {
resolveFile: (specifier: string) => string;
resolveScript: (specifier: string) => string;
}

export function rewriteHtml(html: string, {resolveFile = String, resolveScript = String}: HtmlResolvers): string {
export function rewriteHtml(
html: string,
{resolveFile = String, resolveScript = String}: Partial<HtmlResolvers>
): string {
const {document} = parseHtml(html);

const maybeResolveFile = (specifier: string): string => {
return isAssetPath(specifier) ? resolveFile(specifier) : specifier;
};

for (const [selector, src] of ASSET_PROPERTIES) {
for (const [selector, src] of ASSET_ATTRIBUTES) {
for (const element of document.querySelectorAll(selector)) {
const source = decodeURI(element.getAttribute(src)!);
element.setAttribute(src, src === "srcset" ? resolveSrcset(source, maybeResolveFile) : maybeResolveFile(source));
Expand Down
23 changes: 17 additions & 6 deletions src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import mime from "mime";
import type {Config, Page, Script, Section} from "./config.js";
import {mergeToc} from "./config.js";
import {getClientPath} from "./files.js";
import type {Html} from "./html.js";
import {html, parseHtml, rewriteHtml} from "./html.js";
import type {Html, HtmlResolvers} from "./html.js";
import {html, parseHtml, reresolveHtmlPaths as moveHtmlPaths, rewriteHtml} from "./html.js";

Check warning on line 6 in src/render.ts

View workflow job for this annotation

GitHub Actions / test (20, ubuntu-latest)

Member 'moveHtmlPaths' of the import declaration should be sorted alphabetically.

Check warning on line 6 in src/render.ts

View workflow job for this annotation

GitHub Actions / test (20, windows-latest)

Member 'moveHtmlPaths' of the import declaration should be sorted alphabetically.

Check warning on line 6 in src/render.ts

View workflow job for this annotation

GitHub Actions / test (21, ubuntu-latest)

Member 'moveHtmlPaths' of the import declaration should be sorted alphabetically.

Check warning on line 6 in src/render.ts

View workflow job for this annotation

GitHub Actions / test (21, windows-latest)

Member 'moveHtmlPaths' of the import declaration should be sorted alphabetically.
import {transpileJavaScript} from "./javascript/transpile.js";
import type {MarkdownPage} from "./markdown.js";
import type {PageLink} from "./pager.js";
Expand Down Expand Up @@ -80,7 +80,7 @@ ${preview ? `\nopen({hash: ${JSON.stringify(resolvers.hash)}, eval: (body) => ev
</script>${sidebar ? html`\n${await renderSidebar(title, pages, root, path, search, normalizeLink)}` : ""}${
toc.show ? html`\n${renderToc(findHeaders(page), toc.label)}` : ""
}
<div id="observablehq-center">${renderHeader(options, data)}
<div id="observablehq-center">${renderHeader(path, options, data, resolvers)}
<main id="observablehq-main" class="observablehq${draft ? " observablehq--draft" : ""}">
${html.unsafe(rewriteHtml(page.html, resolvers))}</main>${renderFooter(path, options, data, normalizeLink)}
</div>
Expand Down Expand Up @@ -230,9 +230,20 @@ function renderModulePreload(href: string): Html {
return html`\n<link rel="modulepreload" href="${href}">`;
}

function renderHeader({header}: Pick<Config, "header">, data: MarkdownPage["data"]): Html | null {
if (data?.header !== undefined) header = data?.header;
return header ? html`\n<header id="observablehq-header">\n${html.unsafe(header)}\n</header>` : null;
function renderHeader(
path: string,
{header}: Pick<Config, "header">,
data: MarkdownPage["data"],
resolvers: HtmlResolvers
): Html | null {
if (data?.header !== undefined) {
header = data?.header;
} else if (header) {
header = moveHtmlPaths(header, path);
}
return header
? html`\n<header id="observablehq-header">\n${html.unsafe(rewriteHtml(header, resolvers))}\n</header>`
: null;
}

function renderFooter(
Expand Down

0 comments on commit bbfc152

Please sign in to comment.