diff --git a/core/build.rs b/core/build.rs index 125a626..6bdeb6a 100644 --- a/core/build.rs +++ b/core/build.rs @@ -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" diff --git a/core/src/build.rs b/core/src/build.rs index d68a9ee..33ff5a0 100644 --- a/core/src/build.rs +++ b/core/src/build.rs @@ -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); diff --git a/core/src/build/asset_hashes.rs b/core/src/build/asset_hashes.rs index ecafc4c..60b475b 100644 --- a/core/src/build/asset_hashes.rs +++ b/core/src/build/asset_hashes.rs @@ -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 { diff --git a/core/src/build/assets/REUSE.toml b/core/src/build/assets/REUSE.toml index 1d8c42e..e4630d6 100644 --- a/core/src/build/assets/REUSE.toml +++ b/core/src/build/assets/REUSE.toml @@ -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" diff --git a/core/src/build/assets/navigation.js b/core/src/build/assets/navigation.js index ccef79f..4adc6e2 100644 --- a/core/src/build/assets/navigation.js +++ b/core/src/build/assets/navigation.js @@ -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; diff --git a/core/src/build/assets/shortcuts.js b/core/src/build/assets/shortcuts.js new file mode 100644 index 0000000..3c0753c --- /dev/null +++ b/core/src/build/assets/shortcuts.js @@ -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(); + } +}); diff --git a/core/src/build/layout.rs b/core/src/build/layout.rs index 6d4929a..8b1eec3 100644 --- a/core/src/build/layout.rs +++ b/core/src/build/layout.rs @@ -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#""#) - } else { - String::new() - }; + let adaptive_theme_script = format!(r#""#); + 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#""#) - } else { - String::new() - }; + let clipboard_script = format!(r#""#); + 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#""#) - } 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 { "#); - navigation_script = format!(r#""#); + let navigation_script = format!(r#""#); + 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#""#); + scripts.push(shortcuts_script); + + if self.video_script { + let video_js_asset_hash = AssetHashes::VIDEO_JS; + let video_script = format!(r#""#); + 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#" {title} @@ -164,10 +168,7 @@ impl Layout { {extra_meta} - {adaptive_theme_script} - {clipboard_script} - {video_script} - {navigation_script} + {scripts} "#);