Testing of the @doc-json output
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix docsite sidebar rendering, CSS theming, and support file deployment

- Fix sidebar kindBadge: map leaf-page→pg, module-type→MT, etc. (was
showing "L" for leaf-page entries)
- Stop escaping sidebar content HTML (entries contain <code> tags)
- Fix inline sidebar JSON: use Html.cdata_script instead of Html.txt
to prevent HTML-escaping inside <script> tags
- Add --xo-* CSS custom properties for x-ocaml cells in light/dark themes
- Fix support file registration: use 'opam var share' instead of
'opam var x-ocaml:share' (works without x-ocaml being an opam package)
- Suppress empty <li> from config-only extension tags (@x-ocaml.*)
- Add worker_url field to jtw opam findlib_index.json
- Refactor x-ocaml.js worker URL discovery to support both direct
worker_url and day10-style version/content_hash paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+44 -7
+28
src/odoc_docsite_css.ml
··· 17 17 --header-height: 56px; 18 18 --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04); 19 19 --shadow-md: 0 3px 6px rgba(0, 0, 0, 0.08); 20 + 21 + /* x-ocaml interactive cells */ 22 + --xo-bg: var(--code-bg); 23 + --xo-text: var(--text-color); 24 + --xo-gutter-bg: var(--code-bg); 25 + --xo-gutter-text: var(--text-muted); 26 + --xo-gutter-border: var(--border-color); 27 + --xo-stdout-bg: rgba(9, 105, 218, 0.06); 28 + --xo-stdout-text: var(--link-color); 29 + --xo-stderr-bg: rgba(218, 9, 9, 0.06); 30 + --xo-stderr-text: #cf222e; 31 + --xo-meta-bg: var(--code-bg); 32 + --xo-meta-text: var(--text-muted); 33 + --xo-tooltip-bg: var(--content-bg); 34 + --xo-tooltip-text: var(--text-color); 35 + --xo-tooltip-border: var(--border-color); 36 + --xo-btn-bg: var(--code-bg); 37 + --xo-btn-border: var(--border-color); 38 + --xo-btn-text: var(--text-muted); 39 + --xo-btn-hover-bg: var(--text-muted); 40 + --xo-btn-hover-text: var(--content-bg); 20 41 } 21 42 22 43 @media (prefers-color-scheme: dark) { ··· 36 57 --include-bg: rgba(255, 255, 255, 0.02); 37 58 --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2); 38 59 --shadow-md: 0 3px 6px rgba(0, 0, 0, 0.3); 60 + 61 + /* x-ocaml interactive cells - dark overrides */ 62 + --xo-stdout-bg: rgba(88, 166, 255, 0.08); 63 + --xo-stdout-text: #79c0ff; 64 + --xo-stderr-bg: rgba(248, 81, 73, 0.08); 65 + --xo-stderr-text: #f85149; 66 + --xo-meta-text: var(--text-muted); 39 67 } 40 68 } 41 69
+15 -6
src/odoc_docsite_js.ml
··· 28 28 // Sidebar rendering 29 29 function kindBadge(kind) { 30 30 if (!kind) return ''; 31 - const labels = { package: 'P', module: 'M', page: 'pg' }; 31 + const labels = { 32 + 'package': 'P', 'module': 'M', 'module-type': 'MT', 33 + 'page': 'pg', 'leaf-page': 'pg', 'class': 'C', 'class-type': 'CT', 34 + 'library': 'L' 35 + }; 32 36 const label = labels[kind] || kind[0].toUpperCase(); 33 - return '<span class="sidebar-kind sidebar-kind-' + kind + '" title="' + kind + '">' + label + '</span>'; 37 + var cssKind = kind.replace(/[^a-z]/g, '-'); 38 + return '<span class="sidebar-kind sidebar-kind-' + cssKind + '" title="' + kind + '">' + label + '</span>'; 34 39 } 35 40 36 41 function renderSidebarEntry(entry) { ··· 42 47 var isCollapsed = sidebarState[stateKey] !== true; 43 48 var badge = kindBadge(node.kind); 44 49 50 + // Content may contain inline HTML (e.g. <code>odoc</code>), so we 51 + // pass it through as-is rather than escaping it. 52 + var contentHtml = node.content; 53 + 45 54 // Render packages/modules with children as collapsible groups 46 55 if (hasChildren) { 47 56 var childrenHtml = entry.children.map(function(c) { return renderSidebarEntry(c); }).join(''); 48 57 var linkHtml = node.url 49 - ? '<a class="sidebar-link' + (isActive ? ' active' : '') + '" href="' + BASE_URL + node.url + '" data-nav="' + node.url + '">' + badge + escapeHtml(node.content) + '</a>' 50 - : '<span>' + badge + escapeHtml(node.content) + '</span>'; 58 + ? '<a class="sidebar-link' + (isActive ? ' active' : '') + '" href="' + BASE_URL + node.url + '" data-nav="' + node.url + '">' + badge + contentHtml + '</a>' 59 + : '<span>' + badge + contentHtml + '</span>'; 51 60 return '<div class="sidebar-group' + (isCollapsed ? ' collapsed' : '') + '" data-id="' + escapeHtml(stateKey) + '">' + 52 61 '<div class="sidebar-group-header">' + 53 62 '<svg class="sidebar-toggle" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' + ··· 61 70 // Leaf nodes: add spacer for alignment with expandable items 62 71 var spacer = (node.kind === 'package' || node.kind === 'module') 63 72 ? '<span class="sidebar-toggle-spacer"></span>' : ''; 64 - return '<a class="sidebar-link sidebar-leaf' + (isActive ? ' active' : '') + '" href="' + BASE_URL + node.url + '" data-nav="' + node.url + '">' + spacer + badge + escapeHtml(node.content) + '</a>'; 73 + return '<a class="sidebar-link sidebar-leaf' + (isActive ? ' active' : '') + '" href="' + BASE_URL + node.url + '" data-nav="' + node.url + '">' + spacer + badge + contentHtml + '</a>'; 65 74 } else { 66 - return '<span class="sidebar-link">' + badge + escapeHtml(node.content) + '</span>'; 75 + return '<span class="sidebar-link">' + badge + contentHtml + '</span>'; 67 76 } 68 77 } 69 78
+1 -1
src/odoc_docsite_shell.ml
··· 103 103 let json_str = Json.to_string json in 104 104 [ 105 105 Html.script 106 - (Html.txt 106 + (Html.cdata_script 107 107 (Printf.sprintf "window.__DOCSITE_SIDEBAR_DATA__ = %s;" json_str)); 108 108 ] 109 109