Give wikilinks a relative href in static/public HTML
The content-cache renderer (docToHtml) emitted wikilinks without an href, so on the read-only public page view they rendered as styled but unclickable text. Emit href="<slug>" — relative to the current page URL, it resolves to the sibling page under both /public/<pond>/… and the in-app /p/<pond>/… version-history preview, without the renderer needing pond context. Slugs are [a-z0-9-], safe as a bare path segment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EwZ4jR4KFAPvpjWevfUGX1
This commit is contained in:
parent
6b17fa289b
commit
79376bcdd1
@ -63,4 +63,13 @@ describe('docToHtml (issue #24)', () => {
|
|||||||
expect(html).toContain('data-checked="true"');
|
expect(html).toContain('data-checked="true"');
|
||||||
expect(html).toContain('<input type="checkbox" disabled checked>');
|
expect(html).toContain('<input type="checkbox" disabled checked>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('gives wikilinks a relative href so public/static HTML is clickable', () => {
|
||||||
|
const html = docToHtml(markdownToDoc('See [[api-guide|the API guide]].'));
|
||||||
|
// Relative slug href resolves to the sibling page under both
|
||||||
|
// /public/<pond>/… and /p/<pond>/… without pond context in the renderer.
|
||||||
|
expect(html).toContain(
|
||||||
|
'<a class="wikilink" href="api-guide" data-wikilink="api-guide" data-display="the API guide">the API guide</a>',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -57,14 +57,18 @@ function renderInline(node: Node): string {
|
|||||||
const widthAttr = width ? ` width="${width}"` : '';
|
const widthAttr = width ? ` width="${width}"` : '';
|
||||||
out += `<img data-file-id="${escapeHtml(child.attrs.fileId as string)}" alt="${alt}"${widthAttr}>`;
|
out += `<img data-file-id="${escapeHtml(child.attrs.fileId as string)}" alt="${alt}"${widthAttr}>`;
|
||||||
} else if (child.type.name === 'wikilink') {
|
} else if (child.type.name === 'wikilink') {
|
||||||
// The slug and shown text; live title resolution and navigation happen
|
// The slug and shown text; live title resolution happens in the editor
|
||||||
// where the pond's pages are known (issue #46) — this is the static
|
// where the pond's pages are known (issue #46). The href is the target
|
||||||
// representation used for the content cache and version history.
|
// slug *relative* to the current page URL, so this static HTML links
|
||||||
|
// correctly from both the public view (`/public/<pond>/<slug>`) and the
|
||||||
|
// in-app version-history preview (`/p/<pond>/<slug>`) without the
|
||||||
|
// renderer needing the pond context. Slugs are `[a-z0-9-]`, safe as a
|
||||||
|
// bare path segment.
|
||||||
const slug = escapeHtml(child.attrs.targetSlug as string);
|
const slug = escapeHtml(child.attrs.targetSlug as string);
|
||||||
const display = child.attrs.displayText as string | null;
|
const display = child.attrs.displayText as string | null;
|
||||||
const text = escapeHtml(display ?? (child.attrs.targetSlug as string));
|
const text = escapeHtml(display ?? (child.attrs.targetSlug as string));
|
||||||
const displayAttr = display ? ` data-display="${escapeHtml(display)}"` : '';
|
const displayAttr = display ? ` data-display="${escapeHtml(display)}"` : '';
|
||||||
out += `<a class="wikilink" data-wikilink="${slug}"${displayAttr}>${text}</a>`;
|
out += `<a class="wikilink" href="${slug}" data-wikilink="${slug}"${displayAttr}>${text}</a>`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user