From 70b14222ec6d4cddd0a48c0783037acf15838fd9 Mon Sep 17 00:00:00 2001 From: Chris Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com> Date: Thu, 18 Jun 2026 22:39:29 -0400 Subject: [PATCH 1/3] docfx_project: add canonical versions.json stub --- docfx_project/versions.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 docfx_project/versions.json diff --git a/docfx_project/versions.json b/docfx_project/versions.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/docfx_project/versions.json @@ -0,0 +1 @@ +[] From 4120707aeee09dbd859cb8cbd5f89d5f2db44787 Mon Sep 17 00:00:00 2001 From: Chris Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com> Date: Thu, 18 Jun 2026 22:39:30 -0400 Subject: [PATCH 2/3] docfx_project/public: add canonical version-picker.js --- docfx_project/public/version-picker.js | 205 +++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 docfx_project/public/version-picker.js diff --git a/docfx_project/public/version-picker.js b/docfx_project/public/version-picker.js new file mode 100644 index 00000000..d5afe387 --- /dev/null +++ b/docfx_project/public/version-picker.js @@ -0,0 +1,205 @@ +// Version picker for Wolfgang.* DocFX sites. +// +// Reads versions.json from the site root and inserts a . + var select = document.createElement('select'); + select.className = 'wolfgang-version-picker'; + select.setAttribute('aria-label', 'Documentation version'); + + // Light styling — neutral, follows theme colors. + // + // `color-scheme: light dark` tells the browser the element's + // popup can render in either color scheme; the browser then + // picks the right one based on the page's data-bs-theme / OS + // preference. Without this, the OS-rendered popup defaults to + // light mode and the option text ends up white-on-white in + // DocFX modern's dark theme. + select.style.cssText = [ + 'margin-left: 0.75rem', + 'margin-right: 0.5rem', + 'padding: 0.25rem 0.5rem', + 'background: transparent', + 'color: inherit', + 'color-scheme: light dark', + 'border: 1px solid currentColor', + 'border-radius: 4px', + 'font: inherit', + 'cursor: pointer', + 'opacity: 0.85' + ].join('; '); + + var optionCount = 0; + versions.forEach(function (v) { + if (!v || !v.version || !v.url) return; + // Skip the "latest" alias — the highest-numbered v* entry + // already represents the latest release; surfacing both is + // redundant in the picker. versions.json keeps the "latest" + // entry so other consumers (links, scripts) can still + // resolve it. + if (v.version === 'latest') return; + var opt = document.createElement('option'); + opt.value = v.url; + opt.textContent = v.version; + if (v.version === currentVersion) { + opt.selected = true; + } + // Explicit option styling so the OS-rendered popup is + // readable in both themes. Bootstrap variables (used by + // DocFX's modern template) flip automatically with + // data-bs-theme; the fallback values cover non-Bootstrap + // hosts. + opt.style.backgroundColor = 'var(--bs-body-bg, Canvas)'; + opt.style.color = 'var(--bs-body-color, CanvasText)'; + select.appendChild(opt); + optionCount++; + }); + + // No selectable versions (e.g. versions.json contained only the + // "latest" alias, or all entries were malformed) — don't insert + // an empty dropdown. + if (optionCount === 0) return; + + select.addEventListener('change', function (e) { + var target = e.target.value; + if (!target) return; + // versions.json's `url` fields include the gh-pages repo prefix + // (e.g. /DateTime-Extensions/versions/v1.2.0/) because that's + // the correct absolute path on github.io. On localhost or on a + // CNAME-served custom domain, that prefix isn't a directory + // and the navigation 404s. Strip the first path segment when + // we're not on github.io so the URL becomes relative to the + // actual document root. + if (!window.location.hostname.endsWith('.github.io') && target.charAt(0) === '/') { + target = target.replace(/^\/[^\/]+\//, '/'); + } + window.location.href = target; + }); + + // Insert into the DocFX modern-template navbar. + // Anchors are pairs of [selector, mode]: + // - "before" inserts the picker as a sibling immediately before + // the matched element (preferred for the theme toggle / nav + // groups / search box — keeps the picker inline with them). + // - "append" inserts the picker as the LAST child of the matched + // element (used for the
fallback so the picker lands + // INSIDE the header, not as a sibling under ). + // First match wins. + var anchors = [ + ['header #mode', 'before'], + ['header .navbar-nav', 'before'], + ['header form[role="search"]', 'before'], + ['header nav', 'append'], + ['header', 'append'] + ]; + var inserted = false; + for (var i = 0; i < anchors.length; i++) { + var sel = anchors[i][0]; + var mode = anchors[i][1]; + var anchor = document.querySelector(sel); + if (!anchor) continue; + if (mode === 'before' && anchor.parentNode) { + anchor.parentNode.insertBefore(select, anchor); + } else { + anchor.appendChild(select); + } + inserted = true; + break; + } + if (!inserted) { + // Last-resort fallback — pin to top-right. + select.style.position = 'fixed'; + select.style.top = '0.5rem'; + select.style.right = '1rem'; + select.style.zIndex = '1000'; + document.body.appendChild(select); + } + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); From 208bda99c48c4c7d17fd8cf459849588f968286c Mon Sep 17 00:00:00 2001 From: Chris Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com> Date: Thu, 18 Jun 2026 22:39:32 -0400 Subject: [PATCH 3/3] docfx_project/docfx.json: add public/** + versions.json to resource.files --- docfx_project/docfx.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docfx_project/docfx.json b/docfx_project/docfx.json index 3559e29c..e8cef3d7 100644 --- a/docfx_project/docfx.json +++ b/docfx_project/docfx.json @@ -34,9 +34,11 @@ "files": [ "logo.svg", "apple-touch-icon.png", - "favicon.ico", "favicon.svg", - "images/**" + "favicon.ico", + "images/**", + "public/**", + "versions.json" ] } ],