Skip to content

Commit 4bb4197

Browse files
committed
1
1 parent 9cd4677 commit 4bb4197

File tree

3 files changed

+130
-44
lines changed

3 files changed

+130
-44
lines changed

src/components/Encrypt.astro

Lines changed: 121 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/content/docs/astro-starlight/astro-starlight-encrypted.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ editUrl: false
55

66
import PasswordWrapper from '@components/PasswordWrapper.astro';
77

8-
<PasswordWrapper password="example123" passwordSubtitle="密码:example123">
8+
<PasswordWrapper password="123456" passwordSubtitle="密码:123456">
99

1010
# 这是加密的内容
1111

src/styles/password.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
/* 密码容器样式 */
1+
/* 密码容器样式 - 初始隐藏,由 JavaScript 控制显示 */
22
.password-container {
3+
display: none !important;
4+
visibility: hidden !important;
5+
opacity: 0 !important;
6+
}
7+
8+
/* 当需要显示密码界面时,由 JavaScript 添加这个类 */
9+
.password-container.show {
310
display: flex !important;
411
flex-direction: column !important;
512
align-items: center !important;

0 commit comments

Comments
 (0)