fixed bug
This commit is contained in:
1 parent
23eab42bd7
commit
d73ec8bdc1
16 files changed
+1134
-97
No files matched your search
@@ -2,4 +2,40 @@
|
|||||||
- title: "青梅酒不错"
|
- title: "青梅酒不错"
|
||||||
image: "/album/青梅酒.jpg"
|
image: "/album/青梅酒.jpg"
|
||||||
date: "2026-01-29"
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "https://immmmm.com/goods/mxkeys.webp"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "/album/青梅酒.jpg"
|
||||||
|
date: "2026-01-29"
|
||||||
|
description: "青梅酒还不错"
|
||||||
|
- title: "青梅酒不错"
|
||||||
|
image: "https://immmmm.com/goods/mxkeys.webp"
|
||||||
|
date: "2026-01-29"
|
||||||
description: "青梅酒还不错"
|
description: "青梅酒还不错"
|
||||||
@@ -87,13 +87,6 @@ hasCJKLanguage = true
|
|||||||
# 站点参数配置 (Site Parameters)
|
# 站点参数配置 (Site Parameters)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
[params]
|
[params]
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
# 关于页面配置 (About Page Configuration)
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
[params.about]
|
|
||||||
enableheatmap = false # 开启热力图 (Enable Heatmap)
|
|
||||||
enableskills = false # 开启技能栈 (Enable Skills)
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# 社交链接 (Social Links)
|
# 社交链接 (Social Links)
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
@@ -103,6 +96,13 @@ hasCJKLanguage = true
|
|||||||
{ title = "Rss订阅", url = "/rss.xml", icon = "ri-rss-fill" }
|
{ title = "Rss订阅", url = "/rss.xml", icon = "ri-rss-fill" }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# 关于页面配置 (About Page Configuration)
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
[params.about]
|
||||||
|
enableheatmap = false # 开启热力图 (Enable Heatmap)
|
||||||
|
enableskills = false # 开启技能栈 (Enable Skills)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# 作者信息 (Author Info)
|
# 作者信息 (Author Info)
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
@@ -126,6 +126,7 @@ hasCJKLanguage = true
|
|||||||
[params.artalk]
|
[params.artalk]
|
||||||
server = "https://artalk.usj.cc"
|
server = "https://artalk.usj.cc"
|
||||||
site = "优世界"
|
site = "优世界"
|
||||||
|
ai_badge = "捧场王" # 自定义 AI 评论标识
|
||||||
emoticons = "/emotion/OwO.json"
|
emoticons = "/emotion/OwO.json"
|
||||||
gravatar = "https://cravatar.cn/avatar/"
|
gravatar = "https://cravatar.cn/avatar/"
|
||||||
|
|
||||||
|
|||||||
+188
-50
@@ -46,10 +46,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .main {
|
[data-theme="dark"] .main {
|
||||||
background: rgba(15, 23, 42, 0.96);
|
background: rgba(15, 23, 42, 0.99); /* Increased opacity for readability */
|
||||||
box-shadow: var(--card-shadow-dark);
|
box-shadow: var(--card-shadow-dark);
|
||||||
backdrop-filter: blur(10px);
|
/* Removed glassmorphism blur as requested */
|
||||||
-webkit-backdrop-filter: blur(10px);
|
backdrop-filter: none;
|
||||||
|
-webkit-backdrop-filter: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .header nav {
|
[data-theme="dark"] .header nav {
|
||||||
@@ -505,7 +506,7 @@ ul {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 60px auto;
|
margin: 60px auto;
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
background: rgba(255, 255, 255, 0.95);
|
background: rgba(255, 255, 255, 0.8);
|
||||||
box-shadow: var(--card-shadow-light);
|
box-shadow: var(--card-shadow-light);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
@@ -740,93 +741,153 @@ ul {
|
|||||||
animation: fadeIn 0.3s ease;
|
animation: fadeIn 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simplified Search Styles for Essay/Shuoshuo */
|
||||||
.search-input-group {
|
.search-input-group {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-bottom: 2px solid #e5e7eb;
|
border: 1px solid rgba(0, 0, 0, 0.08); /* Very subtle border for minimalism */
|
||||||
transition: border-color 0.3s ease;
|
border-radius: 99px; /* Fully rounded pill */
|
||||||
|
padding: 2px 15px;
|
||||||
|
background: transparent; /* No background by default */
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-group:hover {
|
||||||
|
border-color: rgba(0, 0, 0, 0.15);
|
||||||
|
background: rgba(0, 0, 0, 0.01);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input-group:focus-within {
|
.search-input-group:focus-within {
|
||||||
border-color: #111827;
|
background: #fff;
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08); /* Soft diffuse shadow */
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .search-input-group {
|
||||||
|
border-color: rgba(255, 255, 255, 0.1);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .search-input-group:hover {
|
||||||
|
border-color: rgba(255, 255, 255, 0.2);
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .search-input-group:focus-within {
|
[data-theme="dark"] .search-input-group:focus-within {
|
||||||
border-color: #e5e7eb;
|
background: #1f2933;
|
||||||
|
border-color: transparent;
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input-group input {
|
.search-input-group input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 8px 35px 8px 45px; /* Increased left padding to separate from icon */
|
padding: 10px 10px 10px 30px;
|
||||||
font-size: 1rem;
|
font-size: 0.95rem;
|
||||||
color: var(--text-title-color);
|
color: var(--text-title-color);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .search-input-group input {
|
|
||||||
color: var(--text-title-dark-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon, .close-icon {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon {
|
.search-icon {
|
||||||
left: 5px;
|
position: absolute;
|
||||||
|
left: 15px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #9ca3af;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: color 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-group:focus-within .search-icon {
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .search-input-group:focus-within .search-icon {
|
||||||
|
color: #d1d5db;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-icon {
|
.close-icon {
|
||||||
right: 5px;
|
position: absolute;
|
||||||
|
right: 15px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #9ca3af;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: color 0.2s;
|
transition: all 0.2s;
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input-group.has-value .close-icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-icon:hover {
|
.close-icon:hover {
|
||||||
color: var(--text-title-color);
|
color: #ef4444;
|
||||||
}
|
|
||||||
|
|
||||||
[data-theme="dark"] .close-icon:hover {
|
|
||||||
color: var(--text-title-dark-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-dropdown {
|
.search-dropdown {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
right: 0;
|
||||||
background: rgba(255, 255, 255, 0.98);
|
background: rgba(255, 255, 255, 0.9);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(12px);
|
||||||
border-radius: 8px;
|
-webkit-backdrop-filter: blur(12px);
|
||||||
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
|
border-radius: 12px;
|
||||||
z-index: 100;
|
box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.1);
|
||||||
max-height: 400px;
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
overflow-y: auto;
|
margin-top: 12px;
|
||||||
margin-top: 10px;
|
overflow: hidden;
|
||||||
display: none; /* Hidden by default */
|
z-index: 50;
|
||||||
}
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
[data-theme="dark"] .search-dropdown {
|
visibility: hidden;
|
||||||
background: rgba(30, 41, 59, 0.98);
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
box-shadow: 0 10px 25px rgba(0,0,0,0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-dropdown.show {
|
.search-dropdown.show {
|
||||||
display: block;
|
opacity: 1;
|
||||||
animation: slideDown 0.2s ease;
|
transform: translateY(0);
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .search-dropdown {
|
||||||
|
background: rgba(31, 41, 51, 0.9);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-result-item {
|
.search-result-item {
|
||||||
padding: 12px 15px;
|
padding: 10px 15px;
|
||||||
border-bottom: 1px solid rgba(0,0,0,0.05);
|
border-bottom: 1px solid rgba(0,0,0,0.03);
|
||||||
transition: background 0.2s;
|
display: flex;
|
||||||
text-align: left; /* Align text left */
|
flex-direction: column;
|
||||||
cursor: pointer;
|
}
|
||||||
|
|
||||||
|
.search-result-meta {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-summary-text {
|
||||||
|
max-width: 70%;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-result {
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
padding: 15px;
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .search-result-item {
|
[data-theme="dark"] .search-result-item {
|
||||||
@@ -1001,6 +1062,83 @@ ul {
|
|||||||
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Code Block Controls */
|
||||||
|
.code-controls {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 10px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
z-index: 10;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight:hover .code-controls {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-btn {
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-btn:hover {
|
||||||
|
background: rgba(0,0,0,0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expandable Code Blocks */
|
||||||
|
.highlight.collapsed {
|
||||||
|
max-height: 300px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight.collapsed::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
background: linear-gradient(to bottom, transparent, #f6f8fa);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme="dark"] .highlight.collapsed::after {
|
||||||
|
background: linear-gradient(to bottom, transparent, #282a36);
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-btn-container {
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
z-index: 5;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight.collapsed .expand-btn-container {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-btn {
|
||||||
|
background: var(--link-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 15px;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
[data-theme="dark"] .highlight {
|
[data-theme="dark"] .highlight {
|
||||||
background: #282a36; /* Night Mode: Dark BG (Dracula) */
|
background: #282a36; /* Night Mode: Dark BG (Dracula) */
|
||||||
color: #f8f8f2; /* Night Mode: Light Text */
|
color: #f8f8f2; /* Night Mode: Light Text */
|
||||||
|
|||||||
@@ -5,13 +5,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
ViewImage.init('.post-content img');
|
ViewImage.init('.post-content img');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化各个模块
|
// 文章图片懒加载 (优先初始化,防止其他模块调用时出错)
|
||||||
if (window.initLoader) window.initLoader();
|
|
||||||
if (window.initFloatingTools) window.initFloatingTools();
|
|
||||||
if (window.initSearch) window.initSearch();
|
|
||||||
if (window.initArtalk) window.initArtalk();
|
|
||||||
|
|
||||||
// 文章图片懒加载
|
|
||||||
if (typeof lazyLoadInit === 'function') {
|
if (typeof lazyLoadInit === 'function') {
|
||||||
lazyLoadInit({
|
lazyLoadInit({
|
||||||
offsetBottom: 800,
|
offsetBottom: 800,
|
||||||
@@ -21,4 +15,16 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
} else {
|
} else {
|
||||||
console.warn('lazyLoadInit is not defined');
|
console.warn('lazyLoadInit is not defined');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始化各个模块
|
||||||
|
if (window.initLoader) window.initLoader();
|
||||||
|
if (window.initFloatingTools) window.initFloatingTools();
|
||||||
|
if (window.initSearch) window.initSearch();
|
||||||
|
if (window.initArtalk) window.initArtalk();
|
||||||
|
|
||||||
|
// New Utils Init
|
||||||
|
if (window.initThemeToggle) window.initThemeToggle();
|
||||||
|
if (window.initCodeFold) window.initCodeFold();
|
||||||
|
if (window.initCodeCopy) window.initCodeCopy();
|
||||||
|
if (window.initParagraphComments) window.initParagraphComments();
|
||||||
});
|
});
|
||||||
@@ -33,7 +33,7 @@ window.initArtalk = function() {
|
|||||||
<div class="atk-main" uk-scrollspy="cls: uk-animation-slide-right-small; delay: 300">
|
<div class="atk-main" uk-scrollspy="cls: uk-animation-slide-right-small; delay: 300">
|
||||||
<div class="atk-header">
|
<div class="atk-header">
|
||||||
<span class="atk-nick" uk-scrollspy="cls: uk-animation-slide-top-small; delay: 350">${ai.name}</span>
|
<span class="atk-nick" uk-scrollspy="cls: uk-animation-slide-top-small; delay: 350">${ai.name}</span>
|
||||||
<span class="atk-badge">AI</span>
|
<span class="atk-badge">${window.artalkConfig.aiBadge || 'AI'}</span>
|
||||||
<span class="atk-date">${ai.date}</span>
|
<span class="atk-date">${ai.date}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="atk-body">
|
<div class="atk-body">
|
||||||
@@ -71,20 +71,30 @@ window.initArtalk = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Find all avatars in the comment list
|
// Find all avatars in the comment list
|
||||||
var avatars = document.querySelectorAll('.atk-list .atk-avatar img');
|
// We let lazyload.js handle the avatars automatically by calling lazyLoadAgain()
|
||||||
avatars.forEach(function(img) {
|
// which will find these new images, set the placeholder, and observe them.
|
||||||
var src = img.getAttribute('src');
|
|
||||||
if (src) {
|
|
||||||
img.setAttribute('data-lazy-src', src);
|
|
||||||
img.removeAttribute('src');
|
|
||||||
img.classList.add('lazyload');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trigger lazy load update
|
// Trigger lazy load update
|
||||||
if (window.lazyLoadAgain) {
|
if (window.lazyLoadAgain) {
|
||||||
window.lazyLoadAgain();
|
window.lazyLoadAgain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force hide "No Comment" if AI comment exists
|
||||||
|
if (window.artalkConfig.aiComment) {
|
||||||
|
var checkNoComment = setInterval(function() {
|
||||||
|
var noComment = document.querySelector('.atk-list-no-comment');
|
||||||
|
var aiComment = document.querySelector('.atk-ai-comment');
|
||||||
|
if (aiComment && noComment && noComment.style.display !== 'none') {
|
||||||
|
noComment.style.display = 'none';
|
||||||
|
}
|
||||||
|
if (!document.querySelector('#Comments')) {
|
||||||
|
clearInterval(checkNoComment);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
// Clear interval after 10 seconds to save resources
|
||||||
|
setTimeout(function() { clearInterval(checkNoComment); }, 10000);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -12,26 +12,34 @@
|
|||||||
function init(setting) {
|
function init(setting) {
|
||||||
defaults = Object.assign({}, defaults, setting || {});
|
defaults = Object.assign({}, defaults, setting || {});
|
||||||
|
|
||||||
// Initialize IntersectionObserver
|
// Reset observer for PJAX support
|
||||||
if (!observer) {
|
if (observer) {
|
||||||
observer = new IntersectionObserver(function(entries, self) {
|
observer.disconnect();
|
||||||
entries.forEach(function(entry) {
|
observer = null;
|
||||||
if (entry.isIntersecting) {
|
|
||||||
var img = entry.target;
|
|
||||||
showImg(img);
|
|
||||||
self.unobserve(img);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, {
|
|
||||||
rootMargin: defaults.offsetTopm + "px 0px " + defaults.offsetBottom + "px 0px"
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize IntersectionObserver
|
||||||
|
observer = new IntersectionObserver(function(entries, self) {
|
||||||
|
entries.forEach(function(entry) {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
var img = entry.target;
|
||||||
|
showImg(img);
|
||||||
|
self.unobserve(img);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, {
|
||||||
|
rootMargin: defaults.offsetTopm + "px 0px " + defaults.offsetBottom + "px 0px"
|
||||||
|
});
|
||||||
|
|
||||||
processImages();
|
processImages();
|
||||||
}
|
}
|
||||||
|
|
||||||
function processImages() {
|
function processImages() {
|
||||||
var images = document.querySelectorAll('img:not(.blog-img):not([data-comp])');
|
if (!observer) {
|
||||||
|
init(); // Auto-initialize if not ready
|
||||||
|
}
|
||||||
|
// Expanded selector to catch more images
|
||||||
|
var images = document.querySelectorAll('img.lazyload, img:not(.blog-img):not([data-comp])');
|
||||||
images.forEach(function(img) {
|
images.forEach(function(img) {
|
||||||
// Check if already processed or has data-lazy-src
|
// Check if already processed or has data-lazy-src
|
||||||
if (img.getAttribute('data-lazy-src')) {
|
if (img.getAttribute('data-lazy-src')) {
|
||||||
|
|||||||
@@ -0,0 +1,564 @@
|
|||||||
|
// Paragraph Comments Module
|
||||||
|
(function() {
|
||||||
|
var POPUP_ID = 'selection-popup';
|
||||||
|
|
||||||
|
// CSS for Paragraph Comments
|
||||||
|
var style = document.createElement('style');
|
||||||
|
style.innerHTML = `
|
||||||
|
/* Selection Popup */
|
||||||
|
#${POPUP_ID} {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
background: var(--artalk-editer-color, #333);
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 2147483647;
|
||||||
|
transform: translate(-50%, -120%);
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
transition: opacity 0.2s, transform 0.2s;
|
||||||
|
pointer-events: auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
white-space: nowrap;
|
||||||
|
animation: popIn 0.2s cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||||
|
}
|
||||||
|
#${POPUP_ID}::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -5px;
|
||||||
|
border-width: 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: var(--artalk-editer-color, #333) transparent transparent transparent;
|
||||||
|
}
|
||||||
|
@keyframes popIn {
|
||||||
|
0% { transform: translate(-50%, -100%) scale(0.9); opacity: 0; }
|
||||||
|
100% { transform: translate(-50%, -120%) scale(1); opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Paragraph Comment Marker - Pure Text, No Styles */
|
||||||
|
.paragraph-comment-marker {
|
||||||
|
text-decoration: none !important;
|
||||||
|
border-bottom: none !important;
|
||||||
|
background: transparent !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
cursor: text;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comment Count Bubble - Minimal SVG Style */
|
||||||
|
.paragraph-comment-count {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 16px;
|
||||||
|
padding: 0 4px;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--erji-color, #999);
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-left: 2px;
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
user-select: none;
|
||||||
|
z-index: 10;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paragraph-comment-count svg {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
fill: currentColor;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.paragraph-comment-count:hover {
|
||||||
|
color: var(--theme-color, #4a90e2);
|
||||||
|
background: rgba(0,0,0,0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.paragraph-comment-count:hover svg {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Comments Preview Modal */
|
||||||
|
.pc-modal {
|
||||||
|
position: fixed;
|
||||||
|
top: 0; left: 0; width: 100%; height: 100%;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
.pc-modal.show {
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.pc-modal-content {
|
||||||
|
background: var(--background-color, #fff);
|
||||||
|
width: 90%;
|
||||||
|
max-width: 500px;
|
||||||
|
max-height: 80vh;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
|
||||||
|
transform: translateY(20px);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
.pc-modal.show .pc-modal-content {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
.pc-header {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid var(--frame-color, #eee);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.pc-body {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
.pc-close {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 20px;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
.pc-close:hover { opacity: 1; }
|
||||||
|
.pc-quote-text {
|
||||||
|
padding: 10px;
|
||||||
|
background: var(--bankuai-color, #f6f6f6);
|
||||||
|
border-left: 3px solid var(--text-highlight-color, #666);
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: var(--erji-color, #666);
|
||||||
|
}
|
||||||
|
.pc-comment-item {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
border-bottom: 1px solid var(--frame-color, #eee);
|
||||||
|
}
|
||||||
|
.pc-comment-item:last-child { border-bottom: none; margin-bottom: 0; }
|
||||||
|
.pc-user { font-weight: bold; font-size: 0.9em; margin-bottom: 5px; }
|
||||||
|
.pc-content { font-size: 0.95em; }
|
||||||
|
|
||||||
|
[data-theme="dark"] .pc-modal-content {
|
||||||
|
background: var(--frame-dark-color, #1f2933);
|
||||||
|
color: var(--text-content-dark-color, #d1d5db);
|
||||||
|
}
|
||||||
|
[data-theme="dark"] .pc-quote-text {
|
||||||
|
background: rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
// Create Popup Element
|
||||||
|
var popup = document.createElement('div');
|
||||||
|
popup.id = POPUP_ID;
|
||||||
|
popup.innerHTML = '<span class="icon" style="width:14px;height:14px;fill:currentColor;display:inline-block;"><svg viewBox="0 0 1024 1024" width="100%" height="100%"><path d="M576 128v298.666667h298.666667c0 164.906667-133.76 298.666667-298.666667 298.666666v170.666667c259.2 0 469.333333-210.133333 469.333333-469.333333H576zM149.333333 725.333333c0-164.906667 133.76-298.666667 298.666667-298.666666V128C188.8 128 0 338.133333 0 597.333333h469.333333v-298.666666H170.666667A298.666667 298.666667 0 0 0 149.333333 725.333333z"></path></svg></span> 评论';
|
||||||
|
document.body.appendChild(popup);
|
||||||
|
|
||||||
|
// Create Modal Element
|
||||||
|
var modal = document.createElement('div');
|
||||||
|
modal.className = 'pc-modal';
|
||||||
|
modal.innerHTML = `
|
||||||
|
<div class="pc-modal-content">
|
||||||
|
<div class="pc-header">
|
||||||
|
<span>引用评论</span>
|
||||||
|
<span class="pc-close">×</span>
|
||||||
|
</div>
|
||||||
|
<div class="pc-body"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// State
|
||||||
|
var selectedText = '';
|
||||||
|
var range = null;
|
||||||
|
var isInitialized = false;
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
function init() {
|
||||||
|
if (!isInitialized) {
|
||||||
|
document.addEventListener('mouseup', handleSelection);
|
||||||
|
document.addEventListener('touchend', handleSelection); // Mobile support
|
||||||
|
|
||||||
|
popup.addEventListener('click', handleQuoteClick);
|
||||||
|
modal.querySelector('.pc-close').addEventListener('click', closeModal);
|
||||||
|
modal.addEventListener('click', function(e) {
|
||||||
|
if (e.target === modal) closeModal();
|
||||||
|
});
|
||||||
|
isInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hook into Artalk
|
||||||
|
tryHookArtalk();
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryHookArtalk() {
|
||||||
|
if (window.artalk) {
|
||||||
|
setupArtalkHook(window.artalk);
|
||||||
|
} else {
|
||||||
|
// Performance: Check less frequently (1s) and stop after 10s
|
||||||
|
var checkCount = 0;
|
||||||
|
var checkArtalk = setInterval(function() {
|
||||||
|
checkCount++;
|
||||||
|
if (window.artalk) {
|
||||||
|
clearInterval(checkArtalk);
|
||||||
|
setupArtalkHook(window.artalk);
|
||||||
|
}
|
||||||
|
if (checkCount > 10) clearInterval(checkArtalk); // 10s timeout
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupArtalkHook(artalk) {
|
||||||
|
// Initial load
|
||||||
|
var list = artalk.getCommentList();
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
processComments();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for updates
|
||||||
|
artalk.on('list-loaded', function() {
|
||||||
|
setTimeout(processComments, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performance Optimized: Build Index Once
|
||||||
|
function buildDocumentIndex(root) {
|
||||||
|
var textNodes = [];
|
||||||
|
var allText = "";
|
||||||
|
var nodeOffsets = [];
|
||||||
|
|
||||||
|
var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
|
||||||
|
var node;
|
||||||
|
while (node = walker.nextNode()) {
|
||||||
|
if (node.parentNode && (
|
||||||
|
node.parentNode.tagName === 'SCRIPT' ||
|
||||||
|
node.parentNode.tagName === 'STYLE' ||
|
||||||
|
node.parentNode.classList.contains('paragraph-comment-marker') ||
|
||||||
|
node.parentNode.classList.contains('paragraph-comment-count')
|
||||||
|
)) continue;
|
||||||
|
|
||||||
|
// Skip code blocks
|
||||||
|
if (node.parentElement.closest('pre') || node.parentElement.closest('code')) continue;
|
||||||
|
|
||||||
|
nodeOffsets.push(allText.length);
|
||||||
|
textNodes.push(node);
|
||||||
|
allText += node.nodeValue;
|
||||||
|
}
|
||||||
|
return { textNodes, allText, nodeOffsets };
|
||||||
|
}
|
||||||
|
|
||||||
|
function processComments() {
|
||||||
|
if (!window.artalk) return;
|
||||||
|
|
||||||
|
// Cleanup old markers
|
||||||
|
document.querySelectorAll('.paragraph-comment-marker').forEach(el => {
|
||||||
|
var parent = el.parentNode;
|
||||||
|
if (parent) {
|
||||||
|
parent.replaceChild(document.createTextNode(el.innerText), el);
|
||||||
|
parent.normalize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.paragraph-comment-count').forEach(el => el.remove());
|
||||||
|
|
||||||
|
var comments = window.artalk.getCommentList();
|
||||||
|
var quoteMap = {};
|
||||||
|
|
||||||
|
// Group comments by quote
|
||||||
|
comments.forEach(c => {
|
||||||
|
var content = c.content_marked || c.content;
|
||||||
|
|
||||||
|
// Extract text from HTML blockquotes
|
||||||
|
var tempDiv = document.createElement('div');
|
||||||
|
tempDiv.innerHTML = content;
|
||||||
|
var blockquotes = tempDiv.querySelectorAll('blockquote');
|
||||||
|
|
||||||
|
blockquotes.forEach(bq => {
|
||||||
|
var quoteText = bq.textContent.trim();
|
||||||
|
if (quoteText) {
|
||||||
|
if (!quoteMap[quoteText]) quoteMap[quoteText] = [];
|
||||||
|
if (!quoteMap[quoteText].some(existing => existing.id === c.id)) {
|
||||||
|
quoteMap[quoteText].push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Regex fallback
|
||||||
|
if (!blockquotes.length && c.content && !c.content.includes('<')) {
|
||||||
|
var match = c.content.match(/^> (.*?)(?:\n|$)/gm);
|
||||||
|
if (match) {
|
||||||
|
match.forEach(m => {
|
||||||
|
var q = m.replace(/^> /, '').trim();
|
||||||
|
if (q) {
|
||||||
|
if (!quoteMap[q]) quoteMap[q] = [];
|
||||||
|
if (!quoteMap[q].some(existing => existing.id === c.id)) {
|
||||||
|
quoteMap[q].push(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var postContent = document.querySelector('.post-content') ||
|
||||||
|
document.querySelector('.article-content') ||
|
||||||
|
document.querySelector('article');
|
||||||
|
|
||||||
|
if (!postContent) return;
|
||||||
|
|
||||||
|
// Build Index ONCE
|
||||||
|
var docData = buildDocumentIndex(postContent);
|
||||||
|
|
||||||
|
Object.keys(quoteMap).forEach(quote => {
|
||||||
|
if (quote.length < 2) return;
|
||||||
|
highlightQuote(docData, quote, quoteMap[quote]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Improved Highlight Logic using Pre-built Index
|
||||||
|
function highlightQuote(docData, quote, comments) {
|
||||||
|
if (!quote || quote.length < 5) return;
|
||||||
|
|
||||||
|
var { allText, textNodes, nodeOffsets } = docData;
|
||||||
|
|
||||||
|
// Fuzzy Match
|
||||||
|
var cleanQuote = quote.trim().replace(/\s+/g, ' ');
|
||||||
|
var cleanAllText = allText.replace(/\s+/g, ' ');
|
||||||
|
|
||||||
|
var matchIndex = cleanAllText.indexOf(cleanQuote);
|
||||||
|
|
||||||
|
if (matchIndex === -1) {
|
||||||
|
matchIndex = allText.indexOf(quote);
|
||||||
|
if (matchIndex === -1) matchIndex = allText.indexOf(quote.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchIndex === -1) return;
|
||||||
|
|
||||||
|
// Map back to raw index
|
||||||
|
var currentCleanIndex = 0;
|
||||||
|
var rawStart = -1;
|
||||||
|
var rawEnd = -1;
|
||||||
|
var inWhitespace = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < allText.length; i++) {
|
||||||
|
var char = allText[i];
|
||||||
|
var isSpace = /\s/.test(char);
|
||||||
|
|
||||||
|
if (isSpace) {
|
||||||
|
if (!inWhitespace) {
|
||||||
|
if (currentCleanIndex === matchIndex) rawStart = i;
|
||||||
|
currentCleanIndex++;
|
||||||
|
}
|
||||||
|
inWhitespace = true;
|
||||||
|
} else {
|
||||||
|
if (currentCleanIndex === matchIndex) rawStart = i;
|
||||||
|
currentCleanIndex++;
|
||||||
|
inWhitespace = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawStart !== -1 && currentCleanIndex === matchIndex + cleanQuote.length) {
|
||||||
|
rawEnd = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawStart !== -1 && rawEnd !== -1) {
|
||||||
|
rangeFromOffsets(textNodes, nodeOffsets, rawStart, rawEnd - rawStart, comments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rangeFromOffsets(textNodes, nodeOffsets, start, length, comments) {
|
||||||
|
var end = start + length;
|
||||||
|
var range = document.createRange();
|
||||||
|
|
||||||
|
var startNode = null, startOffset = 0;
|
||||||
|
var endNode = null, endOffset = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < textNodes.length; i++) {
|
||||||
|
var nodeStart = nodeOffsets[i];
|
||||||
|
var nodeEnd = nodeStart + textNodes[i].nodeValue.length;
|
||||||
|
|
||||||
|
if (!startNode && start >= nodeStart && start < nodeEnd) {
|
||||||
|
startNode = textNodes[i];
|
||||||
|
startOffset = start - nodeStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!endNode && end > nodeStart && end <= nodeEnd) {
|
||||||
|
endNode = textNodes[i];
|
||||||
|
endOffset = end - nodeStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startNode && endNode) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startNode && endNode) {
|
||||||
|
try {
|
||||||
|
range.setStart(startNode, startOffset);
|
||||||
|
range.setEnd(endNode, endOffset);
|
||||||
|
wrapRange(range, comments);
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapRange(range, comments) {
|
||||||
|
try {
|
||||||
|
var contents = range.extractContents();
|
||||||
|
var span = document.createElement('span');
|
||||||
|
span.className = 'paragraph-comment-marker';
|
||||||
|
|
||||||
|
span.appendChild(contents);
|
||||||
|
range.insertNode(span);
|
||||||
|
addBubble(span, comments.length, comments);
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBubble(marker, count, comments) {
|
||||||
|
var bubble = document.createElement('sup');
|
||||||
|
bubble.className = 'paragraph-comment-count';
|
||||||
|
// Simple Chat Icon SVG
|
||||||
|
bubble.innerHTML = `<svg viewBox="0 0 24 24"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"></path></svg> <span>${count}</span>`;
|
||||||
|
|
||||||
|
marker.appendChild(bubble);
|
||||||
|
|
||||||
|
bubble.addEventListener('click', function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
showCommentsModal(null, comments);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSelection(e) {
|
||||||
|
setTimeout(function() {
|
||||||
|
var sel = window.getSelection();
|
||||||
|
if (sel.rangeCount > 0) {
|
||||||
|
var r = sel.getRangeAt(0);
|
||||||
|
var text = sel.toString().trim();
|
||||||
|
|
||||||
|
var postContent = document.querySelector('.post-content') ||
|
||||||
|
document.querySelector('.article-content') ||
|
||||||
|
document.querySelector('article');
|
||||||
|
|
||||||
|
if (!postContent) return;
|
||||||
|
|
||||||
|
var isInside = postContent.contains(r.commonAncestorContainer);
|
||||||
|
|
||||||
|
if (text.length > 0 && isInside) {
|
||||||
|
selectedText = text;
|
||||||
|
range = r;
|
||||||
|
showPopup(r);
|
||||||
|
} else {
|
||||||
|
hidePopup();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hidePopup();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showPopup(r) {
|
||||||
|
var rect = r.getBoundingClientRect();
|
||||||
|
popup.style.display = 'flex';
|
||||||
|
var top = rect.top + window.scrollY - 40;
|
||||||
|
var left = rect.left + window.scrollX + (rect.width / 2);
|
||||||
|
|
||||||
|
popup.style.top = top + 'px';
|
||||||
|
popup.style.left = left + 'px';
|
||||||
|
popup.style.opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hidePopup() {
|
||||||
|
popup.style.display = 'none';
|
||||||
|
popup.style.opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleQuoteClick() {
|
||||||
|
if (!window.artalk) return;
|
||||||
|
|
||||||
|
var commentsEl = document.getElementById('Comments');
|
||||||
|
if (commentsEl) commentsEl.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
|
||||||
|
var quoteContent = `> ${selectedText}\n\n`;
|
||||||
|
var editor = window.artalk.editor;
|
||||||
|
|
||||||
|
if (editor && typeof editor.setContent === 'function' && typeof editor.getContent === 'function') {
|
||||||
|
editor.setContent(quoteContent + editor.getContent());
|
||||||
|
editor.focus();
|
||||||
|
} else {
|
||||||
|
var textarea = document.querySelector('.atk-textarea');
|
||||||
|
if (textarea) {
|
||||||
|
textarea.value = quoteContent + textarea.value;
|
||||||
|
textarea.focus();
|
||||||
|
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
textarea.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hidePopup();
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showCommentsModal(quote, comments) {
|
||||||
|
var body = modal.querySelector('.pc-body');
|
||||||
|
body.innerHTML = '';
|
||||||
|
|
||||||
|
if (!quote && comments.length > 0) {
|
||||||
|
var firstContent = comments[0].content_marked || comments[0].content;
|
||||||
|
var match = firstContent.match(/<blockquote>(.*?)<\/blockquote>/) || firstContent.match(/^> (.*?)(?:\n|$)/);
|
||||||
|
if (match) quote = match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quote) {
|
||||||
|
body.innerHTML += `<div class="pc-quote-text">${quote}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
comments.forEach(c => {
|
||||||
|
var item = document.createElement('div');
|
||||||
|
item.className = 'pc-comment-item';
|
||||||
|
var cleanContent = c.content.replace(/^> .*?\n+/g, '').replace(/<blockquote>.*?<\/blockquote>/g, '');
|
||||||
|
|
||||||
|
var badgeHtml = '';
|
||||||
|
if (c.badge) {
|
||||||
|
badgeHtml = `<span style="background:${c.badge_color || '#000'};color:#fff;padding:1px 4px;border-radius:4px;font-size:0.8em;margin-left:5px;">${c.badge}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.innerHTML = `
|
||||||
|
<div class="pc-user">${c.nick}${badgeHtml} <span style="font-weight:normal;font-size:0.8em;color:#999;float:right">${c.date}</span></div>
|
||||||
|
<div class="pc-content">${cleanContent}</div>
|
||||||
|
`;
|
||||||
|
body.appendChild(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.classList.add('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
modal.classList.remove('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
window.initParagraphComments = init;
|
||||||
|
init();
|
||||||
|
|
||||||
|
})();
|
||||||
@@ -121,12 +121,24 @@ function initInlineSearch() {
|
|||||||
searchContainer.style.display = 'block';
|
searchContainer.style.display = 'block';
|
||||||
input.focus();
|
input.focus();
|
||||||
loadSearchIndex();
|
loadSearchIndex();
|
||||||
|
// Add Esc key listener
|
||||||
|
document.addEventListener('keydown', escListener);
|
||||||
} else {
|
} else {
|
||||||
header.style.display = 'inline-flex';
|
header.style.display = 'inline-flex';
|
||||||
searchContainer.style.display = 'none';
|
searchContainer.style.display = 'none';
|
||||||
input.value = '';
|
input.value = '';
|
||||||
|
// Remove .has-value class
|
||||||
|
searchContainer.querySelector('.search-input-group').classList.remove('has-value');
|
||||||
resultsContainer.classList.remove('show');
|
resultsContainer.classList.remove('show');
|
||||||
resultsContainer.innerHTML = '';
|
resultsContainer.innerHTML = '';
|
||||||
|
// Remove Esc key listener
|
||||||
|
document.removeEventListener('keydown', escListener);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var escListener = function(e) {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
window.toggleSearchMode(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,8 +149,41 @@ function initInlineSearch() {
|
|||||||
input.parentNode.replaceChild(newInput, input);
|
input.parentNode.replaceChild(newInput, input);
|
||||||
input = newInput;
|
input = newInput;
|
||||||
|
|
||||||
|
// Handle Close Icon Logic
|
||||||
|
var closeIcon = searchContainer.querySelector('.close-icon');
|
||||||
|
if (closeIcon) {
|
||||||
|
// Remove inline onclick handler if present
|
||||||
|
closeIcon.onclick = null;
|
||||||
|
closeIcon.removeAttribute('onclick');
|
||||||
|
|
||||||
|
// Add new custom handler
|
||||||
|
closeIcon.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (input.value.trim().length > 0) {
|
||||||
|
// Clear input
|
||||||
|
input.value = '';
|
||||||
|
input.focus();
|
||||||
|
// Trigger input event to update UI
|
||||||
|
input.dispatchEvent(new Event('input'));
|
||||||
|
} else {
|
||||||
|
// Close search
|
||||||
|
window.toggleSearchMode(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
input.addEventListener('input', function() {
|
input.addEventListener('input', function() {
|
||||||
var query = this.value.trim().toLowerCase();
|
var query = this.value.trim().toLowerCase();
|
||||||
|
var inputGroup = this.closest('.search-input-group');
|
||||||
|
|
||||||
|
// Toggle has-value class
|
||||||
|
if (this.value.length > 0) {
|
||||||
|
inputGroup.classList.add('has-value');
|
||||||
|
} else {
|
||||||
|
inputGroup.classList.remove('has-value');
|
||||||
|
}
|
||||||
|
|
||||||
if (query.length === 0) {
|
if (query.length === 0) {
|
||||||
resultsContainer.classList.remove('show');
|
resultsContainer.classList.remove('show');
|
||||||
@@ -156,10 +201,11 @@ function initInlineSearch() {
|
|||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
var html = results.slice(0, 5).map(function(item) {
|
var html = results.slice(0, 5).map(function(item) {
|
||||||
return `
|
return `
|
||||||
<a href="${item.permalink}" class="search-result-item" style="display:block; text-decoration:none;" onclick="window.toggleSearchMode(false)">
|
<a href="${item.permalink}" class="search-result-item" onclick="window.toggleSearchMode(false)">
|
||||||
<span class="search-result-title">${item.title}</span>
|
<span class="search-result-title">${item.title}</span>
|
||||||
<div style="display:flex; align-items:center;">
|
<div class="search-result-meta">
|
||||||
<span class="search-result-date">${item.date}</span>
|
<span class="search-result-date">${item.date}</span>
|
||||||
|
<span class="search-result-summary-text">${item.summary || ''}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
`;
|
`;
|
||||||
@@ -173,7 +219,7 @@ function initInlineSearch() {
|
|||||||
window.pjax.refresh(resultsContainer);
|
window.pjax.refresh(resultsContainer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resultsContainer.innerHTML = '<div class="search-result-item" style="text-align:center;color:#999;cursor:default;">无搜索结果</div>';
|
resultsContainer.innerHTML = '<div class="search-result-item no-result">暂无相关内容</div>';
|
||||||
resultsContainer.classList.add('show');
|
resultsContainer.classList.add('show');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,3 +6,173 @@ window.isMobile = function() {
|
|||||||
return false; // PC端
|
return false; // PC端
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Toast Message Helper
|
||||||
|
window.showToast = function(text) {
|
||||||
|
if (typeof Qmsg !== 'undefined') {
|
||||||
|
Qmsg.info(text);
|
||||||
|
} else {
|
||||||
|
// Fallback custom toast
|
||||||
|
let toast = document.querySelector('.custom-toast');
|
||||||
|
if (!toast) {
|
||||||
|
toast = document.createElement('div');
|
||||||
|
toast.className = 'custom-toast';
|
||||||
|
toast.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: rgba(0,0,0,0.8);
|
||||||
|
color: white;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
z-index: 9999;
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
pointer-events: none;
|
||||||
|
`;
|
||||||
|
document.body.appendChild(toast);
|
||||||
|
}
|
||||||
|
toast.innerText = text;
|
||||||
|
toast.style.opacity = '1';
|
||||||
|
|
||||||
|
if (window.toastTimeout) clearTimeout(window.toastTimeout);
|
||||||
|
window.toastTimeout = setTimeout(() => {
|
||||||
|
toast.style.opacity = '0';
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Theme Toggle Logic
|
||||||
|
window.initThemeToggle = function() {
|
||||||
|
const avatar = document.getElementById('theme-toggle-avatar');
|
||||||
|
if (!avatar) return;
|
||||||
|
|
||||||
|
// Remove existing listeners to avoid duplicates (if any)
|
||||||
|
const newAvatar = avatar.cloneNode(true);
|
||||||
|
avatar.parentNode.replaceChild(newAvatar, avatar);
|
||||||
|
|
||||||
|
newAvatar.addEventListener('click', function(e) {
|
||||||
|
// Prevent if clicking on something interactive inside (unlikely for avatar)
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const html = document.documentElement;
|
||||||
|
const currentTheme = html.getAttribute('data-theme');
|
||||||
|
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||||
|
|
||||||
|
html.setAttribute('data-theme', newTheme);
|
||||||
|
localStorage.setItem('theme', newTheme);
|
||||||
|
|
||||||
|
window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式');
|
||||||
|
|
||||||
|
// Trigger generic resize event to force charts/etc to redraw if needed
|
||||||
|
window.dispatchEvent(new Event('resize'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Code Folding Logic
|
||||||
|
window.initCodeFold = function() {
|
||||||
|
const codeBlocks = document.querySelectorAll('.highlight');
|
||||||
|
codeBlocks.forEach(block => {
|
||||||
|
// Check height (approx 300px)
|
||||||
|
if (block.offsetHeight > 360) {
|
||||||
|
// Check if already processed
|
||||||
|
if (block.parentNode.classList.contains('code-fold-container')) return;
|
||||||
|
|
||||||
|
// Wrap
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.className = 'code-fold-container collapsed';
|
||||||
|
block.parentNode.insertBefore(wrapper, block);
|
||||||
|
wrapper.appendChild(block);
|
||||||
|
|
||||||
|
// Add Button
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.className = 'code-expand-btn';
|
||||||
|
btn.innerHTML = '<span><i class="ri-arrow-down-s-line" style="margin-right:4px;"></i> 展开代码 / Expand</span>';
|
||||||
|
btn.onclick = function() {
|
||||||
|
wrapper.classList.remove('collapsed');
|
||||||
|
// Hide button after expand, or change to collapse?
|
||||||
|
// Usually just expand is enough.
|
||||||
|
btn.style.display = 'none';
|
||||||
|
};
|
||||||
|
wrapper.appendChild(btn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Code Copy Logic
|
||||||
|
window.initCodeCopy = function() {
|
||||||
|
// Target pre tags that contain code, or .highlight containers
|
||||||
|
const codeBlocks = document.querySelectorAll('pre');
|
||||||
|
|
||||||
|
codeBlocks.forEach(pre => {
|
||||||
|
// Avoid double init
|
||||||
|
if (pre.parentNode.querySelector('.copy-code-btn')) return;
|
||||||
|
if (pre.querySelector('.copy-code-btn')) return;
|
||||||
|
|
||||||
|
// Check if it's inside a highlight block (Hugo usually does .highlight > pre)
|
||||||
|
// We attach button to the pre or the highlight container?
|
||||||
|
// Attaching to pre is safer for positioning.
|
||||||
|
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.className = 'copy-code-btn';
|
||||||
|
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
||||||
|
btn.title = "复制代码 / Copy Code";
|
||||||
|
btn.style.cssText = `
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 5px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 10;
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Show on hover
|
||||||
|
pre.addEventListener('mouseenter', () => btn.style.opacity = '1');
|
||||||
|
pre.addEventListener('mouseleave', () => btn.style.opacity = '0');
|
||||||
|
|
||||||
|
// Handle touch devices
|
||||||
|
if (window.isMobile()) {
|
||||||
|
btn.style.opacity = '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const code = pre.querySelector('code') ? pre.querySelector('code').innerText : pre.innerText;
|
||||||
|
|
||||||
|
if (navigator.clipboard) {
|
||||||
|
navigator.clipboard.writeText(code).then(() => {
|
||||||
|
window.showToast('代码已复制 / Copied!');
|
||||||
|
btn.innerHTML = '<i class="ri-check-line"></i>';
|
||||||
|
setTimeout(() => btn.innerHTML = '<i class="ri-file-copy-line"></i>', 2000);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('Copy failed', err);
|
||||||
|
window.showToast('复制失败 / Failed');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = code;
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.select();
|
||||||
|
document.execCommand('copy');
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
window.showToast('代码已复制 / Copied!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ensure relative positioning
|
||||||
|
if (getComputedStyle(pre).position === 'static') {
|
||||||
|
pre.style.position = 'relative';
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.appendChild(btn);
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -94,6 +94,11 @@ document.addEventListener("pjax:complete", function () {
|
|||||||
// 初始化代码折叠
|
// 初始化代码折叠
|
||||||
if (typeof initCodeFold === 'function') initCodeFold();
|
if (typeof initCodeFold === 'function') initCodeFold();
|
||||||
|
|
||||||
|
// 初始化段落评论
|
||||||
|
if (typeof window.initParagraphComments === 'function') {
|
||||||
|
window.initParagraphComments();
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化友链状态
|
// 初始化友链状态
|
||||||
if (typeof window.initLinkStatus === 'function') {
|
if (typeof window.initLinkStatus === 'function') {
|
||||||
window.initLinkStatus();
|
window.initLinkStatus();
|
||||||
|
|||||||
@@ -7,4 +7,4 @@
|
|||||||
{{- $src = $src | relURL -}}
|
{{- $src = $src | relURL -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
<img data-lazy-src="{{ $src }}" alt="{{ .Text }}" class="lazyload">
|
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-lazy-src="{{ $src }}" alt="{{ .Text }}" class="lazyload">
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
height: 160px;
|
height: 160px;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: rgba(255, 255, 255, 0.4);
|
background: rgba(255, 255, 255, 0.4);
|
||||||
/* Removed backdrop-filter for performance */
|
/* Enhanced Glassmorphism for non-mobile */
|
||||||
/* backdrop-filter: blur(16px) saturate(180%); */
|
backdrop-filter: blur(12px) saturate(120%);
|
||||||
/* -webkit-backdrop-filter: blur(16px) saturate(180%); */
|
-webkit-backdrop-filter: blur(12px) saturate(120%);
|
||||||
border: 1px solid #111827;
|
border: 1px solid #111827;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
transition:
|
transition:
|
||||||
@@ -55,6 +55,18 @@
|
|||||||
overflow: hidden; /* 防止背景图溢出 */
|
overflow: hidden; /* 防止背景图溢出 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mobile Optimization: Remove expensive effects */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.fc-item {
|
||||||
|
backdrop-filter: none !important;
|
||||||
|
-webkit-backdrop-filter: none !important;
|
||||||
|
background: rgba(255, 255, 255, 0.8); /* Higher opacity fallback */
|
||||||
|
}
|
||||||
|
[data-theme="dark"] .fc-item {
|
||||||
|
background: rgba(30, 30, 30, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.friend-circle-list a {
|
.friend-circle-list a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,17 @@
|
|||||||
.atk-loading{
|
.atk-loading{
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
}
|
}
|
||||||
|
.atk-loading-editor-box {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border: 1px solid var(--frame-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
[data-theme="dark"] .atk-loading-editor-box {
|
||||||
|
border-color: var(--frame-dark-color);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
/*对artalk评论暗夜模式进行微调*/
|
/*对artalk评论暗夜模式进行微调*/
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
.atk-pinned-badge {
|
.atk-pinned-badge {
|
||||||
@@ -20,6 +31,21 @@
|
|||||||
<div id="Comments" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
|
<div id="Comments" uk-scrollspy="target: > *; cls: uk-animation-slide-bottom-small; delay: 100">
|
||||||
<!-- Loading Skeleton -->
|
<!-- Loading Skeleton -->
|
||||||
<div class="atk-loading-placeholder">
|
<div class="atk-loading-placeholder">
|
||||||
|
<!-- Editor Skeleton -->
|
||||||
|
<div class="atk-loading-editor-box">
|
||||||
|
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
|
||||||
|
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
|
||||||
|
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
|
||||||
|
<div class="atk-loading-line" style="width: 32%; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="atk-loading-line" style="width: 100%; height: 120px; border-radius: 4px; margin-bottom: 10px;"></div>
|
||||||
|
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||||
|
<div class="atk-loading-line" style="width: 120px; height: 20px; margin-bottom: 0;"></div>
|
||||||
|
<div class="atk-loading-line" style="width: 80px; height: 34px; border-radius: 4px; margin-bottom: 0;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Comment List Skeleton -->
|
||||||
<div class="atk-loading-item">
|
<div class="atk-loading-item">
|
||||||
<div class="atk-loading-avatar"></div>
|
<div class="atk-loading-avatar"></div>
|
||||||
<div class="atk-loading-content">
|
<div class="atk-loading-content">
|
||||||
@@ -45,6 +71,7 @@
|
|||||||
el: '#Comments',
|
el: '#Comments',
|
||||||
server: '{{ .Site.Params.artalk.server }}',
|
server: '{{ .Site.Params.artalk.server }}',
|
||||||
site: '{{ .Site.Params.artalk.site }}',
|
site: '{{ .Site.Params.artalk.site }}',
|
||||||
|
aiBadge: '{{ .Site.Params.artalk.ai_badge | default "AI" }}',
|
||||||
pageKey: '{{ .RelPermalink }}',
|
pageKey: '{{ .RelPermalink }}',
|
||||||
emoticons: '{{ .Site.Params.artalk.emoticons | relURL }}',
|
emoticons: '{{ .Site.Params.artalk.emoticons | relURL }}',
|
||||||
aiComment: {{ if .Params.ai_comment }}
|
aiComment: {{ if .Params.ai_comment }}
|
||||||
|
|||||||
@@ -66,10 +66,11 @@
|
|||||||
{{ $loader := resources.Get "js/modules/loader.js" }}
|
{{ $loader := resources.Get "js/modules/loader.js" }}
|
||||||
{{ $search := resources.Get "js/modules/search.js" }}
|
{{ $search := resources.Get "js/modules/search.js" }}
|
||||||
{{ $floatingTools := resources.Get "js/modules/floating-tools.js" }}
|
{{ $floatingTools := resources.Get "js/modules/floating-tools.js" }}
|
||||||
|
{{ $paragraphComments := resources.Get "js/modules/paragraph-comments.js" }}
|
||||||
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
|
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
|
||||||
{{ $pjaxLib := resources.Get "js/pjax.js" }}
|
{{ $pjaxLib := resources.Get "js/pjax.js" }}
|
||||||
|
|
||||||
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $barrage $utils $loader $search $floatingTools $artalkModule $nprogress $pjaxLib $main $mypjax $message $echarts $tiaozhuan | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
{{ $scripts := slice $iconfont $lightgallery $uikit $easylazyload $viewimage $artalk $barrage $utils $loader $search $floatingTools $paragraphComments $artalkModule $nprogress $pjaxLib $main $mypjax $message $echarts $tiaozhuan | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}
|
||||||
<script src="{{ $scripts.RelPermalink }}"></script>
|
<script src="{{ $scripts.RelPermalink }}"></script>
|
||||||
<script async src="/js/bsz.js"></script>
|
<script async src="/js/bsz.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -52,6 +52,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.documentElement.setAttribute('data-theme', theme);
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
|
||||||
|
// Listen for system changes
|
||||||
|
if (window.matchMedia) {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
// Only switch if user hasn't manually set a preference
|
||||||
|
// Or maybe we should respect system change if user hasn't explicitly locked it?
|
||||||
|
// Common behavior: manual override sticks.
|
||||||
|
if (!localStorage.getItem('theme')) {
|
||||||
|
var newTheme = event.matches ? "dark" : "light";
|
||||||
|
document.documentElement.setAttribute('data-theme', newTheme);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-top">
|
<div class="header-top">
|
||||||
<div class="head_author_img load-memos-editor">
|
<div class="head_author_img load-memos-editor" id="theme-toggle-avatar">
|
||||||
<img src="{{ .Site.Params.author.avatar }}" class="blog-img" width="80" height="80" alt="{{ .Site.Title }}" />
|
<img src="{{ .Site.Params.author.avatar }}" class="blog-img" width="80" height="80" alt="{{ .Site.Title }}" />
|
||||||
<div class="avatar-theme-tip">
|
<div class="avatar-theme-tip">
|
||||||
点击头像切换昼夜
|
点击头像切换昼夜
|
||||||
|
|||||||
Reference in new issue
Block a user