Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed metadata about the current page instead of parsing current path #2440

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 23 additions & 43 deletions src/web/crate_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1384,33 +1384,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);
Expand All @@ -1429,27 +1419,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,
);

Expand Down
32 changes: 2 additions & 30 deletions src/web/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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",
Expand Down
19 changes: 4 additions & 15 deletions static/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
function formatCrateName(crateTitleAndVersion) {
const stringParts = crateTitleAndVersion.split(" ", 2);
return stringParts[0] + ' = "' + stringParts[1] + '"';
}

(function() {
const clipboard = document.getElementById("clipboard");
if (clipboard) {
Expand All @@ -14,23 +9,17 @@ function formatCrateName(crateTitleAndVersion) {
clipboard.innerHTML = resetClipboardIcon;
}

function copyTextHandler() {
const crateTitleAndVersion = document.getElementById("crate-title");
// On rustdoc pages, we use `textTransform: uppercase`, which copies as uppercase.
// To avoid that, reset the styles temporarily.
const oldTransform = crateTitleAndVersion.style.textTransform;
crateTitleAndVersion.style.textTransform = "none";
const temporaryInput = document.createElement("input");
async function copyTextHandler() {
const metadata = JSON.parse(document.getElementById("crate-metadata").innerText)

const temporaryInput = document.createElement("input");
temporaryInput.type = "text";
temporaryInput.value = formatCrateName(crateTitleAndVersion.innerText);
temporaryInput.value = `${metadata.name} = "${metadata.version}"`;

document.body.append(temporaryInput);
temporaryInput.select();
document.execCommand("copy");

temporaryInput.remove();
crateTitleAndVersion.style.textTransform = oldTransform;

clipboard.textContent = "✓";
if (resetClipboardTimeout !== null) {
Expand Down
44 changes: 10 additions & 34 deletions static/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,27 @@ 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;
}
loadedMenus.add(id);
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.
Expand Down Expand Up @@ -94,27 +79,18 @@ 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")) {
loadAjaxMenu(
newMenu,
"platforms",
"platforms list",
"platforms",
innerPath,
);
}
}
Expand Down
19 changes: 17 additions & 2 deletions templates/rustdoc/topbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,25 @@

{# 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
#}<ul class="pure-menu-list">
<script id="crate-metadata" type="application/json">
{# the only text that needs escaping in a <script> is `</`, none of the
values below can include that sequence #}
{
"name": {{ metadata.name | json_encode() | safe }},
"version": {{ metadata.version | json_encode() | safe }}
}
</script>
{%- if krate -%}
<li class="pure-menu-item pure-menu-has-children">
<a href="#" class="pure-menu-link crate-name" title="{{ krate.description }}">
Expand Down Expand Up @@ -137,7 +152,7 @@
<li class="pure-menu-heading">Versions</li>

<li class="pure-menu-item">
<div class="pure-menu pure-menu-scrollable sub-menu" id="releases-list" tabindex="-1">
<div class="pure-menu pure-menu-scrollable sub-menu" id="releases-list" tabindex="-1" data-url="{{ releases_menu_url }}" >
<span class="rotate">{{ "spinner" | fas }}</span>
</div>
</li>
Expand Down Expand Up @@ -211,7 +226,7 @@
</a>

{# Build the dropdown list showing available targets #}
<ul class="pure-menu-children" id="platforms">
<ul class="pure-menu-children" id="platforms" data-url="{{ platform_menu_url }}" >
{%- if metadata.doc_targets|length < DEFAULT_MAX_TARGETS -%}
{%- include "rustdoc/platforms.html" -%}
{%- else -%}
Expand Down
Loading