Skip to main content

yggdrasil/components/
enhance_assets.rs

1//! P5 §8.2 资源边界:增强脚本/样式的按需注入。
2//!
3//! `shell()` 的 `<head>` 全局只保留启动必需的 `yggdrasil-core.js`(阻塞,先于 hydration,
4//! 导航协调器契约不变)与首屏样式;文章、图鉴、changelog 的增强代码
5//! (`yggdrasil-enhance.js`)与灯箱(`lightbox.js/css`)改由需要的组件各自声明:
6//!
7//! - SSR 直达:`leptos_meta` 把标签烤进 head 且带 `defer`,先于 WASM hydration 执行,
8//!   `bridges::globals` 的调用直接命中;
9//! - SPA 首次导航:客户端注入为 async,effect 可能先于脚本执行——迟到的调用由
10//!   core 建立的 `__pendingEnhanceCalls` 队列兜底,脚本尾部 flush 补上。
11//!
12//! `leptos_meta::Script` **不按 `src` 去重**:同页多个
13//! 组件声明同一脚本会插入多个同 src 标签,组件卸载再挂载(站内导航)还会重新执行。
14//! 两个脚本因此都是幂等 IIFE——入口检测到 `window.__init*` 已安装就保留首次实例,
15//! 只补一次 `__flushEnhanceCalls`(源码见 `libs/yggdrasil-core/src/enhance.ts`、
16//! `libs/lightbox/src/index.ts`)。地址的版本号按文件内容生成,见 [`crate::static_assets`]。
17//!
18//! 组件为 `pub(crate)`:纯 head 注入的内部管线,无可视预览,不进图鉴目录
19//! (目录测试只扫描 `pub fn` 组件;同类先例见 theme.rs 的 ThemePreload)。
20
21use leptos::prelude::*;
22use leptos_meta::{Script, Stylesheet};
23
24use crate::static_assets::{self, ENHANCE_JS, LIGHTBOX_CSS, LIGHTBOX_JS};
25
26/// 声明本页需要增强脚本。挂载 PostContent / 目录 / changelog / 图鉴等增强组件的
27/// 页面调用;重复声明无害(脚本是幂等 IIFE,见模块文档)。
28#[component]
29pub(crate) fn EnhanceScript() -> impl IntoView {
30    view! { <Script src=static_assets::url(ENHANCE_JS) defer="true"/> }
31}
32
33/// 声明本页需要灯箱脚本与样式。点击放大在增强脚本就绪后仍可用
34/// (未加载时调用入队,脚本尾部补执行),卸载清理由 `__closeLightboxFor` 承担。
35#[component]
36pub(crate) fn LightboxAssets() -> impl IntoView {
37    view! {
38        <Stylesheet href=static_assets::url(LIGHTBOX_CSS)/>
39        <Script src=static_assets::url(LIGHTBOX_JS) defer="true"/>
40    }
41}