@@ -17,7 +17,7 @@ const encryptedHtml = await encrypt(html, password);
1717<meta name =" robots" content =" noindex, nofollow" />
1818<meta name =" starlight:search" content =" exclude" />
1919
20- <div id =" encryption" class =" password-container" data-search-exclude =" true" data-noindex =" true" style =" display: flex !important; flex-direction: column !important; align-items: center !important; justify-content: center !important; min-height: 400px !important; padding: 2rem !important; text-align: center !important; visibility: visible !important; opacity: 1 !important; width: 100% !important;" >
20+ <div id =" encryption" class =" password-container" data-search-exclude =" true" data-noindex =" true" style =" display: none !important; visibility: hidden !important; opacity: 0 !important;" >
2121 <!-- 锁图标 -->
2222 <div class =" password-icon" >
2323 <svg xmlns =" http://www.w3.org/2000/svg" fill =" none" viewBox =" 0 0 24 24" stroke =" currentColor" stroke-width =" 2" >
@@ -74,11 +74,35 @@ const encryptedHtml = await encrypt(html, password);
7474</div >
7575
7676<script is:inline data-astro-rerun >
77- // 立即确保密码容器可见 - 在页面加载时立即执行
77+ // 在页面加载的最早时机检查是否有保存的密码,如果有则立即隐藏加密界面
7878 (function() {
79- function ensureVisible() {
80- const encryption = document.getElementById("encryption");
81- if (encryption && encryption.classList.contains("password-container")) {
79+ const key = window.location.pathname;
80+ function getItemWithExpire(key) {
81+ try {
82+ const itemStr = localStorage.getItem(key);
83+ if (!itemStr) return null;
84+ const item = JSON.parse(itemStr);
85+ if (new Date().getTime() > item.expire) {
86+ localStorage.removeItem(key);
87+ return null;
88+ }
89+ return item.value;
90+ } catch {
91+ return null;
92+ }
93+ }
94+
95+ // 立即检查是否有保存的密码
96+ const savedPassword = getItemWithExpire(key);
97+ const encryption = document.getElementById("encryption");
98+
99+ if (savedPassword) {
100+ // 如果有保存的密码,保持隐藏状态(初始就是隐藏的)
101+ // 不需要做任何操作,加密界面会保持隐藏
102+ } else {
103+ // 如果没有保存的密码,显示加密界面
104+ if (encryption) {
105+ encryption.classList.add("show");
82106 encryption.style.cssText = `
83107 display: flex !important;
84108 flex-direction: column !important;
@@ -93,18 +117,6 @@ const encryptedHtml = await encrypt(html, password);
93117 `;
94118 }
95119 }
96- // 立即执行
97- ensureVisible();
98- // DOM 加载完成后再次执行
99- if (document.readyState === 'loading') {
100- document.addEventListener('DOMContentLoaded', ensureVisible);
101- } else {
102- ensureVisible();
103- }
104- // 延迟执行确保覆盖任何后续样式
105- setTimeout(ensureVisible, 0);
106- setTimeout(ensureVisible, 100);
107- setTimeout(ensureVisible, 300);
108120 })();
109121
110122 /**
@@ -202,19 +214,24 @@ const encryptedHtml = await encrypt(html, password);
202214 input.style.pointerEvents = "auto";
203215 btn.style.pointerEvents = "auto";
204216
205- // 立即强制设置密码容器可见 - 必须在所有操作之前
206- article.style.cssText = `
207- display: flex !important;
208- flex-direction: column !important;
209- align-items: center !important;
210- justify-content: center !important;
211- min-height: 400px !important;
212- padding: 2rem !important;
213- text-align: center !important;
214- visibility: visible !important;
215- opacity: 1 !important;
216- width: 100% !important;
217- `;
217+ // 检查是否有保存的密码,如果没有则显示加密界面
218+ const hasSavedPassword = getItemWithExpire(key);
219+ if (!hasSavedPassword) {
220+ // 如果没有保存的密码,显示加密界面
221+ article.classList.add("show");
222+ article.style.cssText = `
223+ display: flex !important;
224+ flex-direction: column !important;
225+ align-items: center !important;
226+ justify-content: center !important;
227+ min-height: 400px !important;
228+ padding: 2rem !important;
229+ text-align: center !important;
230+ visibility: visible !important;
231+ opacity: 1 !important;
232+ width: 100% !important;
233+ `;
234+ }
218235
219236 // 隐藏目录(Table of Contents)的函数
220237 const hideTOC = () => {
@@ -386,6 +403,14 @@ const encryptedHtml = await encrypt(html, password);
386403
387404 try {
388405 const html = await decrypt(encrypted, password);
406+
407+ // 停止所有监控和定时器,避免干扰和残影
408+ if (observer) observer.disconnect();
409+ if (hideTOCInterval) {
410+ clearInterval(hideTOCInterval);
411+ hideTOCInterval = null;
412+ }
413+
389414 // 移除密码容器的样式类,恢复为正常内容容器
390415 article.classList.remove("password-container");
391416 // 移除搜索排除标记
@@ -395,11 +420,10 @@ const encryptedHtml = await encrypt(html, password);
395420 article.style.cssText = "";
396421 article.innerHTML = html;
397422
398- // 恢复目录显示
423+ // 恢复目录显示 - 完全清除样式
399424 const hiddenElements = document.querySelectorAll('[data-encrypted-hidden="true"]');
400425 hiddenElements.forEach(el => {
401- el.style.display = "";
402- el.style.visibility = "";
426+ el.style.cssText = ""; // 使用 cssText 完全清除所有样式
403427 el.removeAttribute('data-encrypted-hidden');
404428 });
405429
@@ -440,16 +464,71 @@ const encryptedHtml = await encrypt(html, password);
440464 }
441465 });
442466
443- // 延迟自动解密,确保页面先渲染
444- const savedPassword = getItemWithExpire(key);
445- if (savedPassword && encrypted) {
446- input.value = savedPassword;
447- // 使用更长的延迟,确保页面完全渲染后再解密
448- setTimeout(() => {
449- if (btn && !btn.disabled) {
450- btn.click();
467+ // 自动解密:如果有保存的密码,立即解密(避免显示加密界面)
468+ const autoDecryptPassword = getItemWithExpire(key);
469+ if (autoDecryptPassword && encrypted) {
470+ // 加密界面应该已经在脚本开头被隐藏了,这里确保隐藏(双重保险)
471+ article.style.opacity = "0";
472+ article.style.visibility = "hidden";
473+ article.style.transition = "none";
474+
475+ // 立即执行解密,不等待
476+ (async () => {
477+ try {
478+ const html = await decrypt(encrypted, autoDecryptPassword);
479+ // 移除密码容器的样式类,恢复为正常内容容器
480+ article.classList.remove("password-container");
481+ // 移除搜索排除标记
482+ article.removeAttribute("data-search-exclude");
483+ article.removeAttribute("data-noindex");
484+ // 重置所有内联样式,让内容使用默认的 Starlight 样式
485+ article.style.cssText = "";
486+ article.style.opacity = "1";
487+ article.style.visibility = "visible";
488+ article.innerHTML = html;
489+
490+ // 恢复目录显示
491+ const hiddenElements = document.querySelectorAll('[data-encrypted-hidden="true"]');
492+ hiddenElements.forEach(el => {
493+ el.style.cssText = "";
494+ el.removeAttribute('data-encrypted-hidden');
495+ });
496+
497+ // 恢复页面标题左对齐
498+ const pageTitle = document.querySelector("h1");
499+ if (pageTitle) {
500+ pageTitle.style.textAlign = "";
501+ }
502+
503+ // 移除 noindex meta 标签
504+ const noindexMeta = document.querySelector("meta[name='robots'][content*='noindex']");
505+ if (noindexMeta) {
506+ noindexMeta.setAttribute("content", "index, follow");
507+ }
508+
509+ // 移除搜索排除标记
510+ document.documentElement.removeAttribute('data-search-exclude');
511+ const searchExcludeMeta = document.querySelector("meta[name='starlight:search']");
512+ if (searchExcludeMeta) {
513+ searchExcludeMeta.remove();
514+ }
515+
516+ // 停止所有监控和定时器
517+ if (observer) observer.disconnect();
518+ if (hideTOCInterval) {
519+ clearInterval(hideTOCInterval);
520+ hideTOCInterval = null;
521+ }
522+ } catch (e) {
523+ // 如果自动解密失败,显示加密界面
524+ article.classList.add("show");
525+ article.style.opacity = "1";
526+ article.style.visibility = "visible";
527+ article.style.transition = "";
528+ article.style.display = "flex";
529+ input.value = autoDecryptPassword;
451530 }
452- }, 100 );
531+ })( );
453532 }
454533 }
455534
0 commit comments