142 lines
5.2 KiB
JavaScript
142 lines
5.2 KiB
JavaScript
// Sheet reveal — new theme slides in, covering old theme like pulling a curtain
|
|
function themeSweep(newTheme, callback) {
|
|
var isH = Math.random() < 0.5;
|
|
|
|
var blank = newTheme === 'dark' ? '#111827' : '#fcfaf5';
|
|
var sheet = document.createElement('div');
|
|
sheet.style.cssText =
|
|
'position:fixed;inset:0;z-index:9999;' +
|
|
'background:' + blank + ';' +
|
|
'clip-path:inset(0 0 0 0);' +
|
|
'transition:clip-path 1.2s cubic-bezier(0.4,0,0.2,1);' +
|
|
'will-change:clip-path;';
|
|
document.body.appendChild(sheet);
|
|
|
|
sheet.offsetWidth;
|
|
callback();
|
|
|
|
sheet.style.clipPath = isH ? 'inset(0 0 0 100%)' : 'inset(100% 0 0 0)';
|
|
|
|
sheet.addEventListener('transitionend', function() {
|
|
if (sheet.parentNode) sheet.parentNode.removeChild(sheet);
|
|
});
|
|
}
|
|
|
|
// Toast Message Helper
|
|
window.showToast = function(text, type) {
|
|
if (window.Toast) {
|
|
var t = type || 'info';
|
|
if (typeof window.Toast[t] === 'function') {
|
|
window.Toast[t](text);
|
|
} else {
|
|
window.Toast.info(text);
|
|
}
|
|
}
|
|
};
|
|
|
|
// Theme Toggle Logic
|
|
window.initThemeToggle = function() {
|
|
var avatar = document.getElementById('theme-toggle-avatar');
|
|
if (!avatar) return;
|
|
|
|
var newAvatar = avatar.cloneNode(true);
|
|
avatar.parentNode.replaceChild(newAvatar, avatar);
|
|
|
|
newAvatar.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
var html = document.documentElement;
|
|
var currentTheme = html.getAttribute('data-theme');
|
|
var newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
|
|
|
var apply = function() {
|
|
html.setAttribute('data-theme', newTheme);
|
|
localStorage.setItem('theme', newTheme);
|
|
window.showToast('已切换至 ' + (newTheme === 'dark' ? '深色' : '浅色') + '模式', 'success');
|
|
if (window.artalk && typeof window.artalk.setDarkMode === 'function') {
|
|
window.artalk.setDarkMode(newTheme === 'dark');
|
|
}
|
|
window.dispatchEvent(new Event('resize'));
|
|
};
|
|
|
|
themeSweep(newTheme, apply);
|
|
});
|
|
};
|
|
|
|
// Code Folding Logic
|
|
window.initCodeFold = function() {
|
|
var codeBlocks = document.querySelectorAll('.highlight');
|
|
codeBlocks.forEach(function(block) {
|
|
if (block.offsetHeight > 360) {
|
|
if (block.parentNode.classList.contains('code-fold-container')) return;
|
|
|
|
var wrapper = document.createElement('div');
|
|
wrapper.className = 'code-fold-container collapsed';
|
|
block.parentNode.insertBefore(wrapper, block);
|
|
wrapper.appendChild(block);
|
|
|
|
var btn = document.createElement('button');
|
|
btn.className = 'code-expand-btn';
|
|
btn.innerHTML = '<span><i class="ri-arrow-down-s-line" style="margin-right:4px;"></i> 展开代码 </span>';
|
|
btn.onclick = function() {
|
|
wrapper.classList.remove('collapsed');
|
|
btn.style.display = 'none';
|
|
};
|
|
wrapper.appendChild(btn);
|
|
}
|
|
});
|
|
};
|
|
|
|
// Code Copy Logic
|
|
window.initCodeCopy = function() {
|
|
var codeBlocks = document.querySelectorAll('pre');
|
|
|
|
codeBlocks.forEach(function(pre) {
|
|
if (pre.parentNode.querySelector('.copy-code-btn')) return;
|
|
if (pre.querySelector('.copy-code-btn')) return;
|
|
|
|
var btn = document.createElement('button');
|
|
btn.className = 'copy-code-btn';
|
|
btn.innerHTML = '<i class="ri-file-copy-line"></i>';
|
|
btn.title = "复制代码";
|
|
btn.style.cssText =
|
|
'position:absolute;top:-6px;right:5px;background:transparent;border:none;' +
|
|
'color:#888;cursor:pointer;padding:5px;border-radius:4px;' +
|
|
'transition:all 0.2s;opacity:0;z-index:10;';
|
|
|
|
pre.addEventListener('mouseenter', function() { btn.style.opacity = '1'; });
|
|
pre.addEventListener('mouseleave', function() { btn.style.opacity = '0'; });
|
|
|
|
if (window.isMobile()) { btn.style.opacity = '1'; }
|
|
|
|
btn.addEventListener('click', function(e) {
|
|
e.stopPropagation();
|
|
var code = pre.querySelector('code') ? pre.querySelector('code').innerText : pre.innerText;
|
|
|
|
if (navigator.clipboard) {
|
|
navigator.clipboard.writeText(code).then(function() {
|
|
window.showToast('代码已复制 / Copied!', 'success');
|
|
btn.innerHTML = '<i class="ri-check-line"></i>';
|
|
setTimeout(function() { btn.innerHTML = '<i class="ri-file-copy-line"></i>'; }, 2000);
|
|
}).catch(function() {
|
|
window.showToast('复制失败 / Failed', 'error');
|
|
});
|
|
} else {
|
|
var textarea = document.createElement('textarea');
|
|
textarea.value = code;
|
|
document.body.appendChild(textarea);
|
|
textarea.select();
|
|
document.execCommand('copy');
|
|
document.body.removeChild(textarea);
|
|
window.showToast('代码已复制 / Copied!', 'success');
|
|
}
|
|
});
|
|
|
|
if (getComputedStyle(pre).position === 'static') {
|
|
pre.style.position = 'relative';
|
|
}
|
|
|
|
pre.appendChild(btn);
|
|
});
|
|
};
|