diff --git a/src/web/crate_details.rs b/src/web/crate_details.rs index ae6a0b726..c318861df 100644 --- a/src/web/crate_details.rs +++ b/src/web/crate_details.rs @@ -1503,33 +1503,23 @@ mod tests { platform_links } - fn run_check_links_redir( - env: &TestEnvironment, - url_start: &str, - url_end: &str, - extra: &str, - should_contain_redirect: bool, - ) { - let response = env - .frontend() - .get(&format!("{url_start}{url_end}")) - .send() - .unwrap(); + fn run_check_links_redir(env: &TestEnvironment, url: &str, should_contain_redirect: bool) { + let response = env.frontend().get(url).send().unwrap(); assert!(response.status().is_success()); - let list1 = check_links(response.text().unwrap(), false, should_contain_redirect); + let text = response.text().unwrap(); + let list1 = check_links(text.clone(), false, should_contain_redirect); + // Same test with AJAX endpoint. - let (start, extra_name) = if url_start.starts_with("/crate/") { - ("", "/crate") - } else { - ("/crate", "") - }; - let response = env - .frontend() - .get(&format!( - "{start}{url_start}/menus/platforms{extra_name}{url_end}{extra}" - )) - .send() - .unwrap(); + let platform_menu_url = kuchikiki::parse_html() + .one(text) + .select_first("#platforms") + .expect("invalid selector") + .attributes + .borrow() + .get("data-url") + .expect("data-url") + .to_string(); + let response = env.frontend().get(&platform_menu_url).send().unwrap(); assert!(response.status().is_success()); assert_cache_control(&response, CachePolicy::ForeverInCdn, &env.config()); let list2 = check_links(response.text().unwrap(), true, should_contain_redirect); @@ -1548,27 +1538,17 @@ mod tests { .source_file("README.md", b"storage readme") .create()?; - // FIXME: For some reason, there are target-redirects on non-AJAX lists on docs.rs - // crate pages other than the "default" one. - run_check_links_redir(env, "/crate/dummy/0.4.0", "/features", "", false); - run_check_links_redir(env, "/crate/dummy/0.4.0", "/builds", "", false); - run_check_links_redir(env, "/crate/dummy/0.4.0", "/source/", "", false); - run_check_links_redir(env, "/crate/dummy/0.4.0", "/source/README.md", "", false); + run_check_links_redir(env, "/crate/dummy/0.4.0/features", false); + run_check_links_redir(env, "/crate/dummy/0.4.0/builds", false); + run_check_links_redir(env, "/crate/dummy/0.4.0/source/", false); + run_check_links_redir(env, "/crate/dummy/0.4.0/source/README.md", false); + run_check_links_redir(env, "/crate/dummy/0.4.0", false); - run_check_links_redir(env, "/crate/dummy/0.4.0", "", "/", false); - run_check_links_redir(env, "/dummy/latest", "/dummy", "/", true); - run_check_links_redir( - env, - "/dummy/0.4.0", - "/x86_64-pc-windows-msvc/dummy", - "/", - true, - ); + run_check_links_redir(env, "/dummy/latest/dummy", true); + run_check_links_redir(env, "/dummy/0.4.0/x86_64-pc-windows-msvc/dummy", true); run_check_links_redir( env, - "/dummy/0.4.0", - "/x86_64-pc-windows-msvc/dummy/struct.A.html", - "/", + "/dummy/0.4.0/x86_64-pc-windows-msvc/dummy/struct.A.html", true, ); diff --git a/src/web/routes.rs b/src/web/routes.rs index 392515100..ced014a42 100644 --- a/src/web/routes.rs +++ b/src/web/routes.rs @@ -236,30 +236,6 @@ pub(super) fn build_axum_routes() -> AxumRouter { "/crate/:name/:version/source/*path", get_internal(super::source::source_browser_handler), ) - .route( - "/crate/:name/:version/menus/platforms/crate/", - get_internal(super::crate_details::get_all_platforms_root), - ) - .route( - "/crate/:name/:version/menus/platforms/crate/features", - get_internal(super::crate_details::get_all_platforms_root), - ) - .route( - "/crate/:name/:version/menus/platforms/crate/builds", - get_internal(super::crate_details::get_all_platforms_root), - ) - .route( - "/crate/:name/:version/menus/platforms/crate/builds/*path", - get_internal(super::crate_details::get_all_platforms_root), - ) - .route( - "/crate/:name/:version/menus/platforms/crate/source/", - get_internal(super::crate_details::get_all_platforms_root), - ) - .route( - "/crate/:name/:version/menus/platforms/crate/source/*path", - get_internal(super::crate_details::get_all_platforms_root), - ) .route( "/crate/:name/:version/menus/platforms/:target", get_internal(super::crate_details::get_all_platforms), @@ -269,12 +245,8 @@ pub(super) fn build_axum_routes() -> AxumRouter { get_internal(super::crate_details::get_all_platforms), ) .route( - "/crate/:name/:version/menus/platforms/", - get_internal(super::crate_details::get_all_platforms), - ) - .route( - "/crate/:name/:version/menus/platforms/:target/", - get_internal(super::crate_details::get_all_platforms), + "/crate/:name/:version/menus/platforms", + get_internal(super::crate_details::get_all_platforms_root), ) .route( "/crate/:name/:version/menus/releases/:target", diff --git a/static/menu.js b/static/menu.js index 51f49f919..781394a06 100644 --- a/static/menu.js +++ b/static/menu.js @@ -7,7 +7,7 @@ const updateMenuPositionForSubMenu = (currentMenuSupplier) => { const loadedMenus = new Set(); -function loadAjaxMenu(menu, id, msg, path, extra) { +async function loadAjaxMenu(menu, id, msg) { if (loadedMenus.has(id)) { return; } @@ -15,34 +15,19 @@ function loadAjaxMenu(menu, id, msg, path, extra) { if (!menu.querySelector(".rotate")) { return; } - const releaseListElem = document.getElementById(id); - if (!releaseListElem) { + const listElem = document.getElementById(id); + if (!listElem) { // We're not in a documentation page, so no need to do anything. return; } - const parts = window.location.pathname.split("/"); - let crateName = parts[1]; - let version = parts[2]; - if (crateName === "crate") { - crateName = parts[2]; - version = parts[3]; - path += "/crate"; + const url = listElem.dataset.url; + try { + const response = await fetch(url); + listElem.innerHTML = await response.text(); + } catch (ex) { + console.error(`Failed to load ${msg}: ${ex}`) + listElem.innerHTML = `Failed to load ${msg}`; } - const xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function() { - if (xhttp.readyState !== XMLHttpRequest.DONE) { - return; - } - if (xhttp.status === 200) { - releaseListElem.innerHTML = xhttp.responseText; - } else { - console.error(`Failed to load ${msg}: [${xhttp.status}] ${xhttp.responseText}`); - document.getElementById(id).innerHTML = `Failed to load ${msg}`; - } - }; - console.log(extra, path); - xhttp.open("GET", `/crate/${crateName}/${version}/menus/${path}${extra}`, true); - xhttp.send(); }; // Allow menus to be open and used by keyboard. @@ -94,18 +79,11 @@ function loadAjaxMenu(menu, id, msg, path, extra) { newMenu.className += " pure-menu-active"; backdrop.style.display = "block"; - const parts = window.location.pathname.split("/"); - const startFrom = parts[1] === "crate" ? 4 : 3; - // We get everything except the first crate name and the version. - const innerPath = "/" + parts.slice(startFrom).join("/") - if (newMenu.querySelector("#releases-list")) { loadAjaxMenu( newMenu, "releases-list", "release list", - "releases", - innerPath, ); } else if (newMenu.querySelector("#platforms")) { @@ -113,8 +91,6 @@ function loadAjaxMenu(menu, id, msg, path, extra) { newMenu, "platforms", "platforms list", - "platforms", - innerPath, ); } } diff --git a/templates/rustdoc/topbar.html b/templates/rustdoc/topbar.html index cac38371a..20435e10c 100644 --- a/templates/rustdoc/topbar.html +++ b/templates/rustdoc/topbar.html @@ -2,6 +2,13 @@ {# The url of the current release, `/crate/:name/:version` #} {%- set crate_url = "/crate/" ~ metadata.name ~ "/" ~ metadata.req_version -%} +{%- if current_target -%} + {%- set rest_menu_url = "/" ~ current_target ~ "/" ~ inner_path -%} +{%- else -%} + {%- set rest_menu_url = "" -%} +{%- endif -%} +{%- set platform_menu_url = crate_url ~ "/menus/platforms" ~ rest_menu_url -%} +{%- set releases_menu_url = crate_url ~ "/menus/releases" ~ rest_menu_url -%} {%- include "header/topbar_begin.html" -%}{# extra whitespace unremovable, need to use html tags unaffacted by whitespace T_T @@ -137,7 +144,7 @@