Extract and unconditionally include shortcuts script as stand-alone asset

This commit is contained in:
Simon Repp
2026-08-08 12:12:09 +02:00
parent 96c56d665f
commit 46dbd4472b
7 changed files with 53 additions and 41 deletions
+6 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024-2025 Simon Repp
// SPDX-FileCopyrightText: 2024-2026 Simon Repp
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::hash::{DefaultHasher, Hash, Hasher};
@@ -27,6 +27,11 @@ fn main() {
"FAVICON_PNG"
);
provide_asset_hash(
include_bytes!("src/build/assets/shortcuts.js"),
"SHORTCUTS_JS"
);
provide_asset_hash(
include_bytes!("src/build/assets/video.js"),
"VIDEO_JS"
+6 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024-2025 Simon Repp
// SPDX-FileCopyrightText: 2024-2026 Simon Repp
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::fs;
@@ -75,6 +75,11 @@ pub fn perform_build(context: &Context) {
include_bytes!("build/assets/favicon.png")
).unwrap();
fs::write(
context.build_dir.join("shortcuts.js"),
include_bytes!("build/assets/shortcuts.js")
).unwrap();
styles::generate_site_css(&mut asset_hashes, context, &site);
scripts::generate_video_js(context);
+2 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024-2025 Simon Repp
// SPDX-FileCopyrightText: 2024-2026 Simon Repp
// SPDX-License-Identifier: AGPL-3.0-or-later
/// When we link to assets on the rendered pages, we append a unique asset
@@ -17,6 +17,7 @@ impl AssetHashes {
pub const CLIPBOARD_JS: &str = env!("HYPER8_STATIC_ASSET_HASH_CLIPBOARD_JS");
pub const EMBED_JS: &str = env!("HYPER8_STATIC_ASSET_HASH_EMBED_JS");
pub const FAVICON_PNG: &str = env!("HYPER8_STATIC_ASSET_HASH_FAVICON_PNG");
pub const SHORTCUTS_JS: &str = env!("HYPER8_STATIC_ASSET_HASH_SHORTCUTS_JS");
pub const VIDEO_JS: &str = env!("HYPER8_STATIC_ASSET_HASH_VIDEO_JS");
pub fn new() -> AssetHashes {
+2 -1
View File
@@ -9,8 +9,9 @@ path = [
"embed.js",
"favicon.png",
"navigation.js",
"shortcuts.js",
"site.css",
"video.js"
]
SPDX-FileCopyrightText = "2024-2025 Simon Repp"
SPDX-FileCopyrightText = "2024-2026 Simon Repp"
SPDX-License-Identifier = "AGPL-3.0-or-later"
-11
View File
@@ -3,9 +3,6 @@ const chevronRightIcon = document.querySelector('#chevron_right_icon').content;
const browseButton = document.querySelector('button.browse');
const filterTranscriptInput = document.querySelector('.transcript input');
const shortcutsButton = document.querySelector('button.shortcuts');
const shortcutsPanel = document.querySelector('dialog.shortcuts');
const navigation = document.querySelector('header .navigation');
const searchContainer = document.querySelector('.search');
@@ -433,14 +430,6 @@ function collapseExpand(siteTreeElement, expand = undefined) {
visitContainer(siteContent);
}
shortcutsButton.addEventListener('click', () => {
if (shortcutsPanel.open) {
shortcutsPanel.close();
} else {
shortcutsPanel.show();
}
});
window.addEventListener('keydown', event => {
if (event.target === searchInput ||
event.target === filterTranscriptInput) return;
+10
View File
@@ -0,0 +1,10 @@
const shortcutsButton = document.querySelector('button.shortcuts');
const shortcutsPanel = document.querySelector('dialog.shortcuts');
shortcutsButton.addEventListener('click', () => {
if (shortcutsPanel.open) {
shortcutsPanel.close();
} else {
shortcutsPanel.show();
}
});
+27 -26
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2025 Simon Repp
// SPDX-FileCopyrightText: 2025-2026 Simon Repp
// SPDX-License-Identifier: AGPL-3.0-or-later
use indoc::formatdoc;
@@ -69,6 +69,7 @@ impl Layout {
let e_site_title = html_escape_outside_attribute(site.title());
let mut extra_meta = String::new();
let mut scripts = Vec::new();
if !self.indexing {
extra_meta.push_str(META_ROBOTS_NOINDEX_NOFOLLOW);
@@ -78,35 +79,26 @@ impl Layout {
extra_meta.push_str(&meta_link_tags(translations));
}
let adaptive_theme_script = if let ThemeKind::Adaptive { .. } = site.theme.kind() {
if let ThemeKind::Adaptive { .. } = site.theme.kind() {
let adaptive_theme_js_asset_hash = AssetHashes::ADAPTIVE_THEME_JS;
format!(r#"<script defer src="{root_prefix}adaptive_theme.js?{adaptive_theme_js_asset_hash}"></script>"#)
} else {
String::new()
};
let adaptive_theme_script = format!(r#"<script defer src="{root_prefix}adaptive_theme.js?{adaptive_theme_js_asset_hash}"></script>"#);
scripts.push(adaptive_theme_script);
}
let clipboard_script = if self.clipboard_script {
if self.clipboard_script {
let clipboard_js_asset_hash = AssetHashes::CLIPBOARD_JS;
format!(r#"<script defer src="{root_prefix}clipboard.js?{clipboard_js_asset_hash}"></script>"#)
} else {
String::new()
};
let clipboard_script = format!(r#"<script defer src="{root_prefix}clipboard.js?{clipboard_js_asset_hash}"></script>"#);
scripts.push(clipboard_script);
}
if let Some(meta) = &self.platform_integration_meta {
extra_meta.push_str(&meta.tags(site));
}
let video_script = if self.video_script {
let video_js_asset_hash = AssetHashes::VIDEO_JS;
format!(r#"<script defer src="{root_prefix}video.js?{video_js_asset_hash}"></script>"#)
} else {
String::new()
};
let mut templates = String::new();
let navigation;
let navigation_script;
if let Some(navigation_js_asset_hash) = &asset_hashes.navigation_js {
let browse_icon = hyper8_icons::BROWSE;
let close_icon = hyper8_icons::failure(translations.close);
@@ -135,7 +127,8 @@ impl Layout {
</div>
"#);
navigation_script = format!(r#"<script defer src="{root_prefix}navigation.js?{navigation_js_asset_hash}"></script>"#);
let navigation_script = format!(r#"<script defer src="{root_prefix}navigation.js?{navigation_js_asset_hash}"></script>"#);
scripts.push(navigation_script);
let chevron_right_icon = hyper8_icons::CHEVRON_RIGHT;
let navigation_templates = formatdoc!(r#"
@@ -147,14 +140,25 @@ impl Layout {
templates.push_str(&navigation_templates);
} else {
navigation = String::new();
navigation_script = String::new();
};
}
let shortcuts_js_asset_hash = AssetHashes::SHORTCUTS_JS;
let shortcuts_script = format!(r#"<script defer src="{root_prefix}shortcuts.js?{shortcuts_js_asset_hash}"></script>"#);
scripts.push(shortcuts_script);
if self.video_script {
let video_js_asset_hash = AssetHashes::VIDEO_JS;
let video_script = format!(r#"<script defer src="{root_prefix}video.js?{video_js_asset_hash}"></script>"#);
scripts.push(video_script);
}
let favicon_png_asset_hash = AssetHashes::FAVICON_PNG;
let site_css_asset_hash = asset_hashes.site_css.as_ref().unwrap();
let meta_generator = meta_generator();
let scripts = scripts.join("");
let head = formatdoc!(r#"
<head>
<title>{title}</title>
@@ -164,10 +168,7 @@ impl Layout {
{extra_meta}
<link href="{root_prefix}favicon.png?{favicon_png_asset_hash}" rel="icon" type="image/png">
<link rel="stylesheet" href="{root_prefix}site.css?{site_css_asset_hash}">
{adaptive_theme_script}
{clipboard_script}
{video_script}
{navigation_script}
{scripts}
</head>
"#);