add _extensions
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
title: html
|
||||
author: ming
|
||||
version: 1.0.0
|
||||
quarto-required: ">=1.7.0"
|
||||
contributes:
|
||||
formats:
|
||||
html:
|
||||
toc: true
|
||||
css: _extensions/drwater/dwhm/inst/drwater.css
|
||||
theme: _extensions/drwater/dwhm/inst/drwater.scss
|
||||
@@ -0,0 +1,418 @@
|
||||
// clab-tooltip.js - 完全隔离事件版本(修改后的显示位置逻辑)
|
||||
(function() {
|
||||
// 全局变量存储从 RN.html 提取的内容
|
||||
let rnContentCache = {};
|
||||
let isRnContentLoaded = false;
|
||||
let activeTooltip = null;
|
||||
let hideTimer = null;
|
||||
let isMouseOverTooltip = false;
|
||||
|
||||
// 从 RN.html 提取内容(保持不变)
|
||||
async function loadRnContent() {
|
||||
try {
|
||||
console.log('加载 RN.html...');
|
||||
const response = await fetch('RN.html');
|
||||
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
|
||||
|
||||
const htmlText = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const rnDoc = parser.parseFromString(htmlText, 'text/html');
|
||||
|
||||
// 查找所有包含 data-options 的元素
|
||||
const optionElements = rnDoc.querySelectorAll('[data-options]');
|
||||
console.log(`找到 ${optionElements.length} 个 data-options 元素`);
|
||||
|
||||
optionElements.forEach(element => {
|
||||
const optionValue = element.getAttribute('data-options');
|
||||
if (!optionValue) return;
|
||||
|
||||
// 向前查找最近的 blockquote
|
||||
let prevElement = element.previousElementSibling;
|
||||
let blockquote = null;
|
||||
|
||||
// 先找前一个兄弟元素
|
||||
while (prevElement) {
|
||||
if (prevElement.tagName === 'BLOCKQUOTE') {
|
||||
blockquote = prevElement;
|
||||
break;
|
||||
}
|
||||
prevElement = prevElement.previousElementSibling;
|
||||
}
|
||||
|
||||
// 如果没找到,向上查找
|
||||
if (!blockquote) {
|
||||
let parent = element.parentElement;
|
||||
while (parent) {
|
||||
let sibling = parent.previousElementSibling;
|
||||
while (sibling) {
|
||||
if (sibling.tagName === 'BLOCKQUOTE') {
|
||||
blockquote = sibling;
|
||||
break;
|
||||
}
|
||||
sibling = sibling.previousElementSibling;
|
||||
}
|
||||
if (blockquote) break;
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
}
|
||||
|
||||
if (blockquote) {
|
||||
const lis = blockquote.querySelectorAll('li');
|
||||
if (lis.length > 0) {
|
||||
const liContents = Array.from(lis).map(li => li.textContent.trim());
|
||||
|
||||
if (!rnContentCache[optionValue]) {
|
||||
rnContentCache[optionValue] = [];
|
||||
}
|
||||
|
||||
// 存储所有引用
|
||||
rnContentCache[optionValue].push({
|
||||
contents: liContents
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
isRnContentLoaded = true;
|
||||
|
||||
console.log('内容加载完成');
|
||||
Object.keys(rnContentCache).forEach(key => {
|
||||
console.log(`"${key}": ${rnContentCache[key].length} Questions`);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 创建 tooltip(保持不变)
|
||||
function createTooltip() {
|
||||
const tooltip = document.createElement('div');
|
||||
tooltip.className = 'clab-tooltip';
|
||||
tooltip.id = 'clab-tooltip-element';
|
||||
|
||||
// 完全阻止所有事件冒泡
|
||||
const stopAllEvents = (e) => {
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
// 阻止所有可能的事件
|
||||
const events = [
|
||||
'mousedown', 'mouseup', 'click', 'dblclick',
|
||||
'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave',
|
||||
'wheel', 'scroll',
|
||||
'touchstart', 'touchmove', 'touchend', 'touchcancel',
|
||||
'pointerdown', 'pointermove', 'pointerup', 'pointercancel',
|
||||
'dragstart', 'dragover', 'drop'
|
||||
];
|
||||
|
||||
events.forEach(eventType => {
|
||||
tooltip.addEventListener(eventType, stopAllEvents, true); // 捕获阶段
|
||||
tooltip.addEventListener(eventType, stopAllEvents, false); // 冒泡阶段
|
||||
});
|
||||
|
||||
// 允许 wheel 事件用于滚动,但阻止冒泡
|
||||
tooltip.addEventListener('wheel', function(e) {
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
// 允许默认的滚动行为
|
||||
}, { passive: false });
|
||||
|
||||
// 允许鼠标在 tooltip 内移动
|
||||
tooltip.addEventListener('mousemove', function(e) {
|
||||
e.stopPropagation();
|
||||
}, { passive: true });
|
||||
|
||||
document.body.appendChild(tooltip);
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
// 显示 tooltip - 已修改位置逻辑
|
||||
function showTooltip(element, tooltip) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const optionValue = element.getAttribute('data-options');
|
||||
|
||||
// 清空内容
|
||||
tooltip.innerHTML = '';
|
||||
|
||||
if (rnContentCache[optionValue] && rnContentCache[optionValue].length > 0) {
|
||||
const entries = rnContentCache[optionValue];
|
||||
|
||||
// 标题显示选项
|
||||
const title = document.createElement('div');
|
||||
title.className = 'tooltip-title';
|
||||
title.textContent = optionValue;
|
||||
if (entries.length > 1) {
|
||||
title.textContent += ` (${entries.length} questions)`;
|
||||
}
|
||||
tooltip.appendChild(title);
|
||||
|
||||
// 显示所有引用
|
||||
entries.forEach((entry, entryIndex) => {
|
||||
const content = entry.contents;
|
||||
|
||||
if (content.length === 1) {
|
||||
// 单一条目
|
||||
const entryDiv = document.createElement('div');
|
||||
entryDiv.className = 'entry-single';
|
||||
|
||||
if (entries.length >= 1) {
|
||||
entryDiv.innerHTML = `<span class="q-label">Q${entryIndex + 1}:</span> ${content[0]}`;
|
||||
} else {
|
||||
entryDiv.textContent = content[0];
|
||||
}
|
||||
|
||||
tooltip.appendChild(entryDiv);
|
||||
} else {
|
||||
// 多个条目
|
||||
const entryDiv = document.createElement('div');
|
||||
entryDiv.className = 'entry-multiple';
|
||||
|
||||
if (entries.length > 1) {
|
||||
const header = document.createElement('div');
|
||||
header.className = 'q-header';
|
||||
header.textContent = `Q${entryIndex + 1}:`;
|
||||
entryDiv.appendChild(header);
|
||||
}
|
||||
|
||||
const ol = document.createElement('ol');
|
||||
ol.className = 'q-list';
|
||||
|
||||
content.forEach((item, itemIndex) => {
|
||||
const li = document.createElement('li');
|
||||
li.innerHTML = `<span class="q-sublabel">${entryIndex + 1}.${itemIndex + 1}</span> ${item}`;
|
||||
ol.appendChild(li);
|
||||
});
|
||||
|
||||
entryDiv.appendChild(ol);
|
||||
tooltip.appendChild(entryDiv);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 没有找到内容
|
||||
const noContent = document.createElement('div');
|
||||
noContent.className = 'tooltip-no-content';
|
||||
noContent.textContent = '未找到相关内容';
|
||||
tooltip.appendChild(noContent);
|
||||
}
|
||||
|
||||
// 确保 tooltip 有合适的尺寸
|
||||
tooltip.style.position = 'fixed';
|
||||
tooltip.style.zIndex = '10000';
|
||||
tooltip.style.maxWidth = '400px';
|
||||
tooltip.style.maxHeight = '500px';
|
||||
tooltip.style.overflowY = 'auto';
|
||||
tooltip.style.boxSizing = 'border-box';
|
||||
|
||||
// 首先隐藏并获取尺寸
|
||||
tooltip.style.visibility = 'hidden';
|
||||
tooltip.classList.add('active');
|
||||
document.body.appendChild(tooltip);
|
||||
|
||||
const tooltipWidth = Math.min(tooltip.scrollWidth, 400);
|
||||
const tooltipHeight = Math.min(tooltip.scrollHeight, 500);
|
||||
|
||||
tooltip.style.width = tooltipWidth + 'px';
|
||||
tooltip.style.height = 'auto';
|
||||
|
||||
const padding = 5;
|
||||
const minDistanceFromEdge = 20;
|
||||
|
||||
let left, top;
|
||||
let position = 'right'; // 首选右侧
|
||||
|
||||
// 检查右侧空间
|
||||
if (rect.right + padding + tooltipWidth <= window.innerWidth - minDistanceFromEdge) {
|
||||
// 右侧有足够空间
|
||||
left = rect.right + padding;
|
||||
top = rect.top;
|
||||
position = 'right';
|
||||
} else if (rect.left - padding - tooltipWidth >= minDistanceFromEdge) {
|
||||
// 左侧有足够空间
|
||||
left = rect.left - padding - tooltipWidth;
|
||||
top = rect.top;
|
||||
position = 'left';
|
||||
} else {
|
||||
// 两侧都没有足够空间,显示在下方
|
||||
left = Math.max(
|
||||
minDistanceFromEdge,
|
||||
Math.min(
|
||||
rect.left + (rect.width - tooltipWidth) / 2,
|
||||
window.innerWidth - tooltipWidth - minDistanceFromEdge
|
||||
)
|
||||
);
|
||||
top = rect.bottom + padding;
|
||||
position = 'bottom';
|
||||
}
|
||||
|
||||
// 垂直边界检查 - 确保不超出屏幕
|
||||
if (top + tooltipHeight > window.innerHeight - minDistanceFromEdge) {
|
||||
// 如果下方空间不足,尝试显示在上方
|
||||
if (rect.top - padding - tooltipHeight >= minDistanceFromEdge) {
|
||||
top = rect.top - padding - tooltipHeight;
|
||||
} else {
|
||||
// 上下都不够,显示在中间
|
||||
top = Math.max(
|
||||
minDistanceFromEdge,
|
||||
Math.min(
|
||||
top,
|
||||
window.innerHeight - tooltipHeight - minDistanceFromEdge
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 水平边界检查 - 确保不超出屏幕
|
||||
if (position === 'right' || position === 'left') {
|
||||
left = Math.max(
|
||||
minDistanceFromEdge,
|
||||
Math.min(left, window.innerWidth - tooltipWidth - minDistanceFromEdge)
|
||||
);
|
||||
}
|
||||
|
||||
tooltip.style.left = left + 'px';
|
||||
tooltip.style.top = top + 'px';
|
||||
tooltip.style.visibility = 'visible';
|
||||
|
||||
// 添加一个小箭头指示方向
|
||||
tooltip.setAttribute('data-position', position);
|
||||
|
||||
activeTooltip = tooltip;
|
||||
isMouseOverTooltip = true;
|
||||
|
||||
// 添加 overlay 防止 body 交互
|
||||
addOverlay();
|
||||
}
|
||||
|
||||
// 添加半透明 overlay(保持不变)
|
||||
function addOverlay() {
|
||||
// 移除现有的 overlay
|
||||
removeOverlay();
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'tooltip-overlay';
|
||||
overlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999;
|
||||
background: transparent;
|
||||
pointer-events: none;
|
||||
`;
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
// 将 overlay 的 pointer-events 设为 auto,但阻止所有事件
|
||||
overlay.addEventListener('mousedown', stopEvent, true);
|
||||
overlay.addEventListener('mouseup', stopEvent, true);
|
||||
overlay.addEventListener('click', stopEvent, true);
|
||||
overlay.addEventListener('mousemove', stopEvent, true);
|
||||
overlay.addEventListener('wheel', stopEvent, true);
|
||||
|
||||
function stopEvent(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
e.stopImmediatePropagation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除 overlay(保持不变)
|
||||
function removeOverlay() {
|
||||
const overlay = document.getElementById('tooltip-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏 tooltip(保持不变)
|
||||
function hideTooltip() {
|
||||
if (!isMouseOverTooltip && activeTooltip) {
|
||||
activeTooltip.classList.remove('active');
|
||||
activeTooltip = null;
|
||||
removeOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
// 强制隐藏 tooltip(保持不变)
|
||||
function forceHideTooltip() {
|
||||
if (activeTooltip) {
|
||||
activeTooltip.classList.remove('active');
|
||||
activeTooltip = null;
|
||||
isMouseOverTooltip = false;
|
||||
removeOverlay();
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化(保持不变)
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('初始化 clab-tooltip');
|
||||
|
||||
const clabElements = document.querySelectorAll('.clab[data-options]');
|
||||
console.log(`找到 ${clabElements.length} 个 .clab 元素`);
|
||||
|
||||
if (clabElements.length === 0) return;
|
||||
|
||||
// 加载内容
|
||||
loadRnContent();
|
||||
|
||||
// 创建 tooltip
|
||||
const tooltip = createTooltip();
|
||||
|
||||
// tooltip 鼠标进入/离开
|
||||
tooltip.addEventListener('mouseenter', function() {
|
||||
isMouseOverTooltip = true;
|
||||
clearTimeout(hideTimer);
|
||||
});
|
||||
|
||||
tooltip.addEventListener('mouseleave', function() {
|
||||
isMouseOverTooltip = false;
|
||||
hideTimer = setTimeout(() => {
|
||||
forceHideTooltip();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// 为所有 .clab 元素添加事件监听
|
||||
clabElements.forEach(clab => {
|
||||
clab.addEventListener('mouseenter', function() {
|
||||
clearTimeout(hideTimer);
|
||||
|
||||
setTimeout(() => {
|
||||
if (isRnContentLoaded) {
|
||||
showTooltip(this, tooltip);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
|
||||
clab.addEventListener('mouseleave', function() {
|
||||
hideTimer = setTimeout(() => {
|
||||
hideTooltip();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
// ESC 键隐藏 tooltip
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && activeTooltip) {
|
||||
forceHideTooltip();
|
||||
}
|
||||
});
|
||||
|
||||
// 点击其他地方隐藏 tooltip
|
||||
document.addEventListener('click', function(e) {
|
||||
if (activeTooltip && !activeTooltip.contains(e.target)) {
|
||||
forceHideTooltip();
|
||||
}
|
||||
});
|
||||
|
||||
// 窗口大小改变时隐藏 tooltip
|
||||
window.addEventListener('resize', forceHideTooltip);
|
||||
|
||||
// 滚动时隐藏 tooltip
|
||||
window.addEventListener('scroll', forceHideTooltip);
|
||||
});
|
||||
})();
|
||||
Executable
+384
@@ -0,0 +1,384 @@
|
||||
.udot {
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: rgb(50, 50, 50);
|
||||
text-decoration-style: dashed;
|
||||
text-decoration-thickness: 1px;
|
||||
}
|
||||
|
||||
.good {
|
||||
background-color: forestgreen;
|
||||
color: lightyellow;
|
||||
}
|
||||
|
||||
.bad {
|
||||
background-color: orangered;
|
||||
color: lightyellow;
|
||||
}
|
||||
|
||||
.del {
|
||||
text-decoration-line: line-through;
|
||||
text-decoration-color: rgb(222 13 13);
|
||||
text-decoration-style: initial;
|
||||
text-decoration-thickness: 1.5px;
|
||||
}
|
||||
|
||||
|
||||
.todo {
|
||||
background-color: darkorange;
|
||||
color: lightyellow;
|
||||
}
|
||||
|
||||
.com {
|
||||
background-color: #0025ff;
|
||||
font-weight: bold;
|
||||
color: lightyellow;
|
||||
}
|
||||
|
||||
.add {
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: rgb(222 13 13);
|
||||
background-color: violet;
|
||||
text-decoration-style: initial;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
|
||||
|
||||
del {
|
||||
text-decoration-line: line-through;
|
||||
text-decoration-color: rgb(222 13 13);
|
||||
text-decoration-style: initial;
|
||||
text-decoration-thickness: 1.0px;
|
||||
}
|
||||
|
||||
|
||||
ins {
|
||||
text-decoration-color: rgb(222 93 93);
|
||||
background-color: violet;
|
||||
text-decoration-style: initial;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* clab-style.css */
|
||||
.clab {
|
||||
display: inline !important;
|
||||
position: relative !important;
|
||||
cursor: pointer !important;
|
||||
padding: 2px 4px !important;
|
||||
margin: 0 1px !important;
|
||||
border-radius: 3px !important;
|
||||
font: inherit !important;
|
||||
color: #000000 !important;
|
||||
text-decoration: none !important;
|
||||
vertical-align: baseline !important;
|
||||
line-height: inherit !important;
|
||||
z-index: 1 !important;
|
||||
}
|
||||
|
||||
/* 随机背景色(使用预定义颜色) */
|
||||
.clab:nth-child(10n+1) { background-color: #E3F2FD !important; }
|
||||
.clab:nth-child(10n+2) { background-color: #F3E5F5 !important; }
|
||||
.clab:nth-child(10n+3) { background-color: #E8F5E9 !important; }
|
||||
.clab:nth-child(10n+4) { background-color: #FFF3E0 !important; }
|
||||
.clab:nth-child(10n+5) { background-color: #FCE4EC !important; }
|
||||
.clab:nth-child(10n+6) { background-color: #E0F7FA !important; }
|
||||
.clab:nth-child(10n+7) { background-color: #F1F8E9 !important; }
|
||||
.clab:nth-child(10n+8) { background-color: #FFF8E1 !important; }
|
||||
.clab:nth-child(10n+9) { background-color: #EDE7F6 !important; }
|
||||
.clab:nth-child(10n+10) { background-color: #E8EAF6 !important; }
|
||||
|
||||
/* 基础hover效果 */
|
||||
span.clab:hover {
|
||||
outline: 2px solid rgba(0,0,0,0.2) !important;
|
||||
outline-offset: 2px !important;
|
||||
z-index: 1000 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* clab-tooltip 下方显示样式 */
|
||||
.clab-tooltip {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
border: 1px solid #444;
|
||||
/* -webkit-user-select: none; */
|
||||
position: fixed;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
border-radius: 8px;
|
||||
z-index: 10000;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3),
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
font-size: 14px;
|
||||
line-height: 1.1;
|
||||
max-width: 500px;
|
||||
max-height: 800px;
|
||||
overflow-y: auto;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
|
||||
overscroll-behavior: contain;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip 箭头 */
|
||||
.tooltip-arrow {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-bottom-color: #2a2a2a;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
/* tooltip 在上方的箭头(向下) */
|
||||
.clab-tooltip.above .tooltip-arrow {
|
||||
border-top-color: #2a2a2a;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.tooltip-title {
|
||||
font-weight: 600;
|
||||
color: #FF9800;
|
||||
margin-bottom: 6px;
|
||||
padding-bottom: 4px;
|
||||
border-bottom: 1px solid #444;
|
||||
font-size: 14px;
|
||||
font-family: monospace;
|
||||
line-height: 0.8;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 单一条目 */
|
||||
.entry-single {
|
||||
padding: 4px 4px;
|
||||
margin-bottom: 6px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 6px;
|
||||
border-left: 3px solid #ffffff;
|
||||
line-height: 1.2;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* Q标签样式 */
|
||||
.q-label {
|
||||
display: inline-block;
|
||||
color: #FF9800;
|
||||
font-weight: 600;
|
||||
margin-right: 8px;
|
||||
min-width: 35px;
|
||||
}
|
||||
|
||||
/* 多个条目的引用 */
|
||||
.entry-multiple {
|
||||
padding: 4px 4px;
|
||||
margin-bottom: 6px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 6px;
|
||||
border-left: 3px solid #ffffff;
|
||||
line-height: 1.2;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* 多引用标题 */
|
||||
.q-header {
|
||||
color: #FF9800;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 列表 */
|
||||
.q-list {
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.q-list li {
|
||||
margin-bottom: 10px;
|
||||
padding-left: 0;
|
||||
line-height: 1.2;
|
||||
position: relative;
|
||||
cursor: default;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
/* 子标签样式 */
|
||||
.q-sublabel {
|
||||
display: inline-block;
|
||||
color: #4CAF50;
|
||||
font-weight: 600;
|
||||
margin-right: 2px;
|
||||
min-width: 25px;
|
||||
}
|
||||
|
||||
/* 条目间空行 */
|
||||
/* .entry-spacer { */
|
||||
/* height: 12px; */
|
||||
/* pointer-events: none; */
|
||||
/* } */
|
||||
|
||||
/* 无内容 */
|
||||
.tooltip-no-content {
|
||||
color: #ff6b6b;
|
||||
font-style: italic;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: rgba(255, 107, 107, 0.05);
|
||||
border-radius: 6px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* 滚动条 */
|
||||
.clab-tooltip::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.clab-tooltip::-webkit-scrollbar-track {
|
||||
background: #1a1a1a;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.clab-tooltip::-webkit-scrollbar-thumb {
|
||||
background: #4CAF50;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.clab-tooltip::-webkit-scrollbar-thumb:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
|
||||
|
||||
/* 允许内容文本选择 */
|
||||
.entry-single,
|
||||
.entry-multiple,
|
||||
.q-list li {
|
||||
user-select: text;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
/* 鼠标在 tooltip 上时的样式 */
|
||||
.clab-tooltip:hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
||||
.clab-tooltip.active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.clab-tooltip ul {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.clab-tooltip li {
|
||||
margin-bottom: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.clab-tooltip .source {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid rgba(255,255,255,0.1);
|
||||
font-size: 11px;
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.clab-tooltip .entry {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
.clab-tooltip .entry:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.rem {
|
||||
background-color: darkorange;
|
||||
color: lightyellow;
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
|
||||
|
||||
#criticnav {
|
||||
position: fixed;
|
||||
z-index: 1100;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 120px;
|
||||
border-bottom: solid 1px #ffffff;
|
||||
margin: 0;
|
||||
padding: 10;
|
||||
background-color: rgb(143 38 38 / 95%);
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-family: "Helvetica Neue", helvetica, arial, sans-serif !important
|
||||
}
|
||||
|
||||
#criticnav ul {
|
||||
list-style-type: none;
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
#criticnav ul li {
|
||||
display: block;
|
||||
width: 100px;
|
||||
min-width: 80px;
|
||||
text-align: center;
|
||||
padding: 5px 0 3px !important;
|
||||
margin: 5px 2px !important;
|
||||
line-height: 1em;
|
||||
float: center;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-radius: 20px;
|
||||
border: 3px solid rgba(255,255,255,0);
|
||||
color: #fff !important
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: left; /* 小屏幕左对齐 */
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
p {
|
||||
text-align: justify;
|
||||
hyphens: auto; /* 自动断字 */
|
||||
-webkit-hyphens: auto; /* Safari 支持 */
|
||||
/* 可选:控制断字行为 */
|
||||
hyphenate-limit-chars: 6 3 2; /* 最小单词长度 前/后最小字符数 */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
body .page-columns {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
grid-template-columns: [screen-start] 0.5em [screen-start-inset] 0fr [page-start page-start-inset] 5px [body-start-outset] 5px [body-start] 0.5em [body-content-start] minmax(350px, calc(855px - 0em)) [body-content-end] 0.5em [body-end] 5px [body-end-outset] minmax(75px, 550px) [page-end-inset] 1px [page-end] 1fr [screen-end-inset] 0.5em [screen-end];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
body .page-columns {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
grid-template-columns: [screen-start] 3.5em [screen-start-inset] 2fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 3.5em [body-content-start] minmax(500px, calc(850px - 3em)) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 400px) [page-end-inset] 35px [page-end] 2fr [screen-end-inset] 1.5em [screen-end];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,415 @@
|
||||
/*-- scss:defaults --*/
|
||||
|
||||
$theme: "drwater" !default;
|
||||
|
||||
//
|
||||
// Color system
|
||||
//
|
||||
|
||||
$white: #ffffff !default;
|
||||
$gray-100: #f8f9fa !default;
|
||||
$gray-200: #e9ecef !default;
|
||||
$gray-300: #dee2e6 !default;
|
||||
$gray-400: #ced4da !default;
|
||||
$gray-500: #adb5bd !default;
|
||||
$gray-600: #868e96 !default;
|
||||
$gray-700: #495057 !default;
|
||||
$gray-800: #373a3c !default;
|
||||
$gray-900: #212529 !default;
|
||||
$black: #000000 !default;
|
||||
|
||||
$blue: #2780e3 !default;
|
||||
$indigo: #6610f2 !default;
|
||||
$purple: #170c3a !default;
|
||||
$pink: #a52c60 !default;
|
||||
$red: #cf4446 !default;
|
||||
$orange: #ee6a24 !default;
|
||||
$light-orange: #fb9e07 !default;
|
||||
$yellow: #f6d645 !default;
|
||||
$green: #118230 !default;
|
||||
$teal: #20c997 !default;
|
||||
$cyan: #3093cf !default;
|
||||
|
||||
$primary: $pink !default;
|
||||
$secondary: $gray-700 !default;
|
||||
$success: $green !default;
|
||||
$info: $cyan !default;
|
||||
$warning: $orange !default;
|
||||
$danger: $red !default;
|
||||
$light: $gray-400 !default;
|
||||
$dark: $black !default;
|
||||
|
||||
// Fonts
|
||||
|
||||
$font-family-sans-serif: "Libre Franklin" !default;
|
||||
|
||||
$headings-font-family: "Jost" !default;
|
||||
$headings-font-weight: 600 !default;
|
||||
|
||||
$navbar-font-family: "Jost" !default;
|
||||
$toc-font-family: "Jost" !default;
|
||||
$footer-font-family: "Jost" !default;
|
||||
|
||||
// Body
|
||||
$body-color: $gray-900 !default;
|
||||
|
||||
// Links
|
||||
$link-color: $orange !default;
|
||||
$link-decoration: none !default;
|
||||
$link-hover-color: $red !default;
|
||||
$link-hover-decoration: underline !default;
|
||||
|
||||
// Inline code
|
||||
$code-bg: $gray-200 !default;
|
||||
$code-color: $gray-900 !default;
|
||||
|
||||
// Code copy
|
||||
$btn-code-copy-color-active: $orange !default;
|
||||
|
||||
// TOC
|
||||
$toc-color: $orange;
|
||||
$toc-font-size: 1em;
|
||||
|
||||
// Navbar
|
||||
$navbar-bg: $purple !default;
|
||||
$navbar-fg: $white !default;
|
||||
$navbar-hl: $light-orange !default;
|
||||
|
||||
// Footer
|
||||
$footer-bg: $gray-900 !default;
|
||||
$footer-fg: $gray-300 !default;
|
||||
|
||||
/*-- scss:rules --*/
|
||||
|
||||
$web-font-path: "https://fonts.googleapis.com/css2?family=Jost:ital,wght@0,100..900;1,100..900&family=Libre+Franklin:ital,wght@0,100..900;1,100..900&display=swap" !default;
|
||||
|
||||
@if $web-font-path {
|
||||
@import url($web-font-path);
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* Logo 悬停效果 */
|
||||
.navbar-brand img {
|
||||
transition: all 0.3s ease;
|
||||
filter: brightness(0) invert(1);
|
||||
|
||||
&:hover {
|
||||
filter: brightness(0) invert(0.55) sepia(1) saturate(2000%) hue-rotate(-8deg) brightness(1.05) contrast(1.2);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 桌面端样式 - 使用悬停展开下拉菜单
|
||||
// =============================================
|
||||
@media (min-width: 992px) {
|
||||
/* 导航栏主菜单项样式 */
|
||||
.navbar-nav .nav-item {
|
||||
position: relative;
|
||||
margin: 0 0.2rem;
|
||||
|
||||
.nav-link {
|
||||
position: relative;
|
||||
color: $navbar-fg !important;
|
||||
font-weight: 500;
|
||||
padding: 0.75rem 1rem !important;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 1;
|
||||
|
||||
/* 玻璃效果背景 */
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba($white, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 8px;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
z-index: -1;
|
||||
border: 1px solid rgba($white, 0.2);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $light-orange !important;
|
||||
transform: translateY(-2px);
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
background: rgba($white, 0.15);
|
||||
backdrop-filter: blur(15px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
/* 激活状态 */
|
||||
&.active {
|
||||
color: $light-orange !important;
|
||||
font-weight: 600;
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
background: rgba($light-orange, 0.2);
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba($light-orange, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 有下拉菜单的主菜单项特殊样式 */
|
||||
.navbar-nav .nav-item.dropdown {
|
||||
.nav-link {
|
||||
padding-right: 2rem !important;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .nav-link::before {
|
||||
opacity: 1;
|
||||
background: rgba($white, 0.2);
|
||||
backdrop-filter: blur(20px);
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
&:hover .nav-link::after {
|
||||
transform: translateY(-50%) rotate(-180deg);
|
||||
border-top-color: $light-orange;
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面端下拉菜单悬停效果 */
|
||||
.navbar-nav .nav-item.dropdown:hover .dropdown-menu {
|
||||
display: block !important;
|
||||
opacity: 1 !important;
|
||||
visibility: visible !important;
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
display: block;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(-10px);
|
||||
transition: all 0.3s ease;
|
||||
background: rgba($purple, 0.98) !important;
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba($white, 0.1);
|
||||
border-top: none;
|
||||
border-radius: 0 0 8px 8px;
|
||||
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.2);
|
||||
margin-top: -1px;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: $white !important;
|
||||
font-family: $navbar-font-family;
|
||||
padding: 0.75rem 1.5rem;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
|
||||
/* 下拉菜单项的玻璃效果 */
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba($white, 0.05);
|
||||
border-radius: 4px;
|
||||
opacity: 0;
|
||||
transition: all 0.2s ease;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&:hover, &:focus {
|
||||
color: $light-orange !important;
|
||||
transform: translateX(5px);
|
||||
background: transparent !important;
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
background: rgba($white, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 确保下拉菜单与主菜单视觉上连接 */
|
||||
.navbar-nav .nav-item.dropdown:hover .nav-link {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 移动端样式 - 使用点击展开下拉菜单
|
||||
// =============================================
|
||||
@media (max-width: 991.98px) {
|
||||
/* 完全重置移动端导航样式,使用 Bootstrap 默认行为 */
|
||||
.navbar-collapse {
|
||||
background: rgba($purple, 0.98);
|
||||
backdrop-filter: blur(10px);
|
||||
border-top: 1px solid rgba($white, 0.1);
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.5rem 0;
|
||||
|
||||
.navbar-nav {
|
||||
.nav-item {
|
||||
margin: 0;
|
||||
|
||||
.nav-link {
|
||||
color: $navbar-fg !important;
|
||||
padding: 1rem 1.5rem !important;
|
||||
border-radius: 0;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
color: $light-orange !important;
|
||||
background: rgba($white, 0.1);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $light-orange !important;
|
||||
background: rgba($light-orange, 0.1);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* 下拉菜单项样式 */
|
||||
&.dropdown {
|
||||
.dropdown-toggle::after {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
&.show {
|
||||
.dropdown-toggle {
|
||||
color: $light-orange !important;
|
||||
background: rgba($white, 0.15);
|
||||
|
||||
&::after {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
background: rgba(darken($purple, 5%), 0.95) !important;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: static;
|
||||
float: none;
|
||||
display: none;
|
||||
|
||||
&.show {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端下拉菜单项 */
|
||||
.dropdown-item {
|
||||
color: $navbar-fg !important;
|
||||
padding: 0.875rem 1.5rem 0.875rem 2.5rem !important;
|
||||
border-radius: 0;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover, &:focus {
|
||||
color: $light-orange !important;
|
||||
background: rgba($white, 0.1) !important;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $light-orange !important;
|
||||
background: rgba($light-orange, 0.1) !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端导航栏折叠按钮 */
|
||||
.navbar-toggler {
|
||||
border: 1px solid rgba($white, 0.2);
|
||||
padding: 0.5rem 0.75rem;
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 0.2rem rgba($light-orange, 0.25);
|
||||
}
|
||||
|
||||
.navbar-toggler-icon {
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.8%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
|
||||
}
|
||||
}
|
||||
|
||||
/* 禁用桌面端的悬停效果 */
|
||||
.navbar-nav .nav-item .nav-link::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-nav .nav-item.dropdown:hover .dropdown-menu {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// 通用样式
|
||||
// =============================================
|
||||
|
||||
/* 导航栏整体样式 */
|
||||
.navbar {
|
||||
backdrop-filter: blur(10px);
|
||||
background: rgba($purple, 0.95) !important;
|
||||
border-bottom: 1px solid rgba($white, 0.1);
|
||||
}
|
||||
|
||||
/* 为有下拉菜单的导航项添加视觉指示 */
|
||||
.navbar-nav .nav-item.dropdown > .nav-link::after {
|
||||
display: inline-block;
|
||||
margin-left: 0.255em;
|
||||
vertical-align: 0.255em;
|
||||
content: "";
|
||||
border-top: 0.3em solid;
|
||||
border-right: 0.3em solid transparent;
|
||||
border-bottom: 0;
|
||||
border-left: 0.3em solid transparent;
|
||||
}
|
||||
|
||||
/* 确保 Bootstrap 的 JavaScript 交互正常工作 */
|
||||
.navbar-nav .dropdown-toggle::after {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
/* 修复移动端点击事件 */
|
||||
.navbar-nav .nav-item.dropdown .nav-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: Untitled
|
||||
format:
|
||||
dwhm-html: default
|
||||
author: Ming Su
|
||||
date: last-modified
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
*TODO* Create an example file that demonstrates the formatting and features of your format.
|
||||
|
||||
## More Information
|
||||
|
||||
You can learn more about controlling the appearance of HTML output here: <https://quarto.org/docs/output-formats/html-basics.html>
|
||||
|
||||
Reference in New Issue
Block a user