Skip to content

Commit

Permalink
Fixes to "staying on the same page functionality"
Browse files Browse the repository at this point in the history
This is squidfunk#7350 with the tests removed, as requested in
squidfunk#7350 (comment) .

I do urge you to reconsider and merge something like squidfunk#7350 (including
the tests I wrote) instead. Without tests, I suspect this code will
break like its [previous version did](
squidfunk@ceacfe5)
. Once the code does break, it might be difficult to fix without tests.

Even if other parts of the theme work without tests, and even if you aren't in love with
how I set up the infrastructure in squidfunk#7350 or squidfunk#7338, I think this logic is complex enough
to need tests to be maintainable. Again, I wouldn't be able to check this code's correctness
without the tests that aren't included in this PR. 

Of course, this is your project to maintain, so do what works best for you. I just hope
this bugfix helps.

---------------------

Fixes squidfunk#7226

Additionally, this allows using the version switcher even if the website
is published at a different URL than the `site_url`. In particular,
the version switcher should now work locally when serving the site with
`mike serve`.
  • Loading branch information
ilyagr committed Sep 24, 2024
1 parent c6286de commit 6c4ba45
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 13 deletions.
1 change: 0 additions & 1 deletion docs/setup/setting-up-versioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ MkDocs implements this behavior by default, but there are a few caveats:
- the [`site_url`][mkdocs.site_url] must be set correctly in `mkdocs.yml`.
See the ["Publishing a new version"](#publishing-a-new-version) section for
an example.
- you must be viewing the site at that URL (and not locally, for example).
- the redirect happens via JavaScript and there is no way to know which page you
will be redirected to ahead of time.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Sitemap } from "../sitemap"

type CorrespondingURLParams = {
selectedVersionSitemap: Sitemap
selectedVersionBaseURL: URL
currentLocation: URL
currentBaseURL: string
}

/**
* Choose a URL to navigate to when the user chooses a version in the version
* selector.
*
* @param selectedVersionSitemap - as obtained by fetchSitemap from `${selectedVersionBaseURL}/sitemap.xml`
* @param selectedVersionBaseURL - usually `${currentBaseURL}/../selectedVersion`
* @param currentLocation - current web browser location
* @param currentBaseURL - as obtained from `config.base`
* @returns the URL to navigate to or null if we can't be sure that the
* corresponding page to the current page exists in the selected version
*/
export function selectedVersionCorrespondingURL(
{selectedVersionSitemap,
selectedVersionBaseURL,
currentLocation,
currentBaseURL}: CorrespondingURLParams
): URL | undefined {
const current_path = (new URL(currentBaseURL)).pathname
const currentRelativePath = stripPrefix(currentLocation.pathname, current_path)
if (currentRelativePath === undefined) {
return
}
const sitemapCommonPrefix = shortestCommonPrefix(selectedVersionSitemap.keys())
if (!selectedVersionSitemap.has(sitemapCommonPrefix)) {
// We could also check that `commonSitemapPrefix` ends in the canonical version,
// similarly to https://github.com/squidfunk/mkdocs-material/pull/7227. However,
// I don't believe that Mike/MkDocs ever generate sitemaps where it would matter
return
}

const potentialSitemapURL = new URL(currentRelativePath, sitemapCommonPrefix)
if (!selectedVersionSitemap.has(potentialSitemapURL.href)) {
return
}

const result = new URL(currentRelativePath, selectedVersionBaseURL)
result.hash = currentLocation.hash
result.search = currentLocation.search
return result
}

// Basic string manipulation

/**
*
* @param s - string
* @param prefix - prefix to strip
*
* @returns either the string with the prefix stripped or undefined if the
* string did not begin with the prefix.
*/
export function stripPrefix(s: string, prefix: string): string | undefined {
if (s.startsWith(prefix)) {
return s.slice(prefix.length)
}
return undefined
}

/**
*
* @param s1 - first string
* @param s2 - second string
*
* @returns - the length of the longest common prefix of the two strings.
*/
function commonPrefixLen(s1: string, s2: string): number {
const max = Math.min(s1.length, s2.length)
let result
for (result = 0; result < max; ++result) {
if (s1[result] !== s2[result]) {
break
}
}
return result
}

/**
*
* @param strs - an iterable of strings
*
* @returns the longest common prefix of all the strings
*/
export function shortestCommonPrefix(strs: Iterable<string>): string {
let result // Undefined if no iterations happened
for (const s of strs) {
if (result === undefined) {
result = s
} else {
result = result.slice(0, commonPrefixLen(result, s))
}
}
return result ?? ""
}
27 changes: 15 additions & 12 deletions src/templates/assets/javascripts/integrations/version/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import {

import { fetchSitemap } from "../sitemap"

import { selectedVersionCorrespondingURL } from "./correspondingPage"

/* ----------------------------------------------------------------------------
* Helper types
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -122,22 +124,23 @@ export function setupVersionSelector(
return EMPTY
}
ev.preventDefault()
return of(url)
return of(new URL(url))
}
}
return EMPTY
}),
switchMap(url => {
return fetchSitemap(new URL(url))
.pipe(
map(sitemap => {
const location = getLocation()
const path = location.href.replace(config.base, url)
return sitemap.has(path.split("#")[0])
? new URL(path)
: new URL(url)
})
)
switchMap(selectedVersionBaseURL => {
return fetchSitemap(selectedVersionBaseURL).pipe(
map(
sitemap =>
selectedVersionCorrespondingURL({
selectedVersionSitemap: sitemap,
selectedVersionBaseURL,
currentLocation: getLocation(),
currentBaseURL: config.base
}) ?? selectedVersionBaseURL,
),
)
})
)
)
Expand Down

0 comments on commit 6c4ba45

Please sign in to comment.