diff --git a/doc/index.php b/doc/index.php new file mode 100644 index 0000000..b1fe8e5 --- /dev/null +++ b/doc/index.php @@ -0,0 +1,121 @@ + 2) ? $pathParts[1] : ''; +$title = ucfirst($pageName); +if (!empty($fileParam) && file_exists($mdFile) && is_file($mdFile)) { + $rawContent = file_get_contents($mdFile); +} else { + $rawContent = ''; + $title = '未找到'; +} +if ($isAjax) { + echo $rawContent; + exit; +} +function getDirStructure($dir, $base = '') { + $items = []; + $entries = scandir($dir); + foreach ($entries as $entry) { + if ($entry === '.' || $entry === '..') continue; + $path = $dir . '/' . $entry; + $rel = $base ? $base . '/' . $entry : $entry; + if (is_dir($path)) { + $items[] = ['type' => 'dir', 'name' => $entry, 'path' => $rel, 'children' => getDirStructure($path, $rel)]; + } elseif (pathinfo($path, PATHINFO_EXTENSION) === 'md') { + $items[] = ['type' => 'file', 'name' => $entry, 'path' => $rel]; + } + } + return $items; +} +$tree = getDirStructure($baseDir); +function renderTree($items, $currentFile) { + $html = ''; + return $html; +} +?> + + + + + + <?php echo htmlspecialchars($title); ?> - Parlz Domains Docs + + + +
+ +
+
+ +Parlz Domains Docs + +
+
+ + + +

暂无文档

+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/doc/script.js b/doc/script.js new file mode 100644 index 0000000..dda5788 --- /dev/null +++ b/doc/script.js @@ -0,0 +1,198 @@ +document.addEventListener('DOMContentLoaded', function() { + const markdownBody = document.getElementById('markdownBody'); + const rawContent = markdownBody.innerHTML; + markdownBody.innerHTML = marked.parse(rawContent); + + const themeToggle = document.getElementById('themeToggle'); + const mobileThemeToggle = document.getElementById('mobileThemeToggle'); + const html = document.documentElement; + + function setTheme(theme) { + html.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + } + + function toggleTheme() { + const current = html.getAttribute('data-theme'); + setTheme(current === 'dark' ? 'light' : 'dark'); + } + + const saved = localStorage.getItem('theme'); + if (saved) { + setTheme(saved); + } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) { + setTheme('dark'); + } + + themeToggle.addEventListener('click', toggleTheme); + if (mobileThemeToggle) mobileThemeToggle.addEventListener('click', toggleTheme); + + const menuToggle = document.getElementById('menuToggle'); + const sidebar = document.querySelector('.sidebar'); + const overlay = document.getElementById('overlay'); + + if (menuToggle) { + menuToggle.addEventListener('click', function() { + sidebar.classList.toggle('open'); + overlay.classList.toggle('show'); + }); + } + + if (overlay) { + overlay.addEventListener('click', function() { + sidebar.classList.remove('open'); + overlay.classList.remove('show'); + }); + } + + const folders = document.querySelectorAll('.folder-toggle'); + folders.forEach(function(folder) { + folder.addEventListener('click', function() { + const li = this.parentElement; + li.classList.toggle('open'); + }); + }); + + const searchInput = document.getElementById('searchInput'); + if (searchInput) { + searchInput.addEventListener('input', function() { + const query = this.value.toLowerCase().trim(); + const files = document.querySelectorAll('.nav-tree .file'); + const dirs = document.querySelectorAll('.nav-tree .folder'); + + if (!query) { + files.forEach(f => f.classList.remove('hidden')); + dirs.forEach(d => d.classList.remove('hidden')); + return; + } + + files.forEach(function(file) { + const text = file.textContent.toLowerCase(); + if (text.includes(query)) { + file.classList.remove('hidden'); + let parent = file.parentElement; + while (parent) { + if (parent.classList && parent.classList.contains('folder')) { + parent.classList.remove('hidden'); + parent.classList.add('open'); + } + parent = parent.parentElement; + } + } else { + file.classList.add('hidden'); + } + }); + + dirs.forEach(function(dir) { + const visibleFiles = dir.querySelectorAll('.file:not(.hidden)'); + if (visibleFiles.length === 0) { + const folderText = dir.querySelector('.folder-toggle').textContent.toLowerCase(); + if (!folderText.includes(query)) { + dir.classList.add('hidden'); + } + } + }); + }); + } + + const currentFile = document.querySelector('.nav-tree .file.active'); + if (currentFile) { + let parent = currentFile.parentElement; + while (parent) { + if (parent.classList && parent.classList.contains('folder')) { + parent.classList.add('open'); + } + parent = parent.parentElement; + } + currentFile.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + + const navTree = document.getElementById('navTree'); + if (navTree) { + navTree.addEventListener('click', function(e) { + const link = e.target.closest('a'); + if (!link) return; + const href = link.getAttribute('href'); + if (!href || href.startsWith('http') || href.startsWith('#') || href.startsWith('javascript')) return; + e.preventDefault(); + + const sidebarEl = document.querySelector('.sidebar'); + const overlayEl = document.getElementById('overlay'); + if (sidebarEl.classList.contains('open')) { + sidebarEl.classList.remove('open'); + overlayEl.classList.remove('show'); + } + + history.pushState(null, '', href); + loadDoc(href); + }); + } + + // ===== 使用 XMLHttpRequest 替代 fetch ===== + function loadDoc(href) { + var url = '/doc/index.php' + href + '&_ajax=1'; + markdownBody.style.opacity = '0.5'; + + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.timeout = 30000; // 30秒超时 + + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + markdownBody.style.opacity = '1'; + + if (xhr.status === 200) { + var data = xhr.responseText; + // 检查是否返回了 HTML(说明请求失败) + if (data.trim().startsWith(' ul { +display: none; +padding-left: 12px; +} + +.nav-tree .folder.open > ul { +display: block; +} + +.nav-tree .file a { +display: flex; +align-items: center; +gap: 6px; +padding: 6px 20px 6px 32px; +color: var(--text-secondary); +text-decoration: none; +font-size: 0.875rem; +transition: all 0.2s; +border-left: 2px solid transparent; +} + +.nav-tree .file a:hover { +color: var(--accent-color); +background: var(--bg-secondary); +} + +.nav-tree .file.active a { +color: var(--accent-color); +background: var(--bg-secondary); +border-left-color: var(--accent-color); +font-weight: 500; +} + +.nav-tree .file.hidden, +.nav-tree .folder.hidden { +display: none; +} + +.content { +margin-left: 280px; +flex: 1; +min-height: 100vh; +} + +.mobile-header { +display: none; +padding: 12px 20px; +background: var(--bg-sidebar); +border-bottom: 1px solid var(--border-color); +align-items: center; +gap: 12px; +position: sticky; +top: 0; +z-index: 50; +} + +.menu-toggle { +background: none; +border: none; +font-size: 1.5rem; +color: var(--text-primary); +cursor: pointer; +padding: 4px; +} + +.mobile-title { +font-weight: 600; +font-size: 1rem; +flex: 1; +color: var(--text-primary); +} + +.markdown-body { +padding: 40px 48px; +max-width: 900px; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { +margin-top: 2rem; +margin-bottom: 1rem; +font-weight: 600; +line-height: 1.3; +color: var(--text-primary); +} + +.markdown-body h1 { font-size: 2rem; border-bottom: 1px solid var(--border-color); padding-bottom: 0.5rem; } +.markdown-body h2 { font-size: 1.5rem; border-bottom: 1px solid var(--border-color); padding-bottom: 0.4rem; } +.markdown-body h3 { font-size: 1.25rem; } +.markdown-body h4 { font-size: 1.1rem; } + +.markdown-body p { +margin-bottom: 1rem; +color: var(--text-secondary); +} + +.markdown-body a { +color: var(--accent-color); +text-decoration: none; +} + +.markdown-body a:hover { +text-decoration: underline; +} + +.markdown-body ul, +.markdown-body ol { +margin-bottom: 1rem; +padding-left: 1.5rem; +color: var(--text-secondary); +} + +.markdown-body li { +margin-bottom: 0.25rem; +} + +.markdown-body code { +background: var(--code-bg); +color: var(--code-text); +padding: 2px 6px; +border-radius: 4px; +font-family: var(--font-mono); +font-size: 0.875em; +} + +.markdown-body pre { +background: var(--code-bg); +border-radius: var(--radius); +padding: 1rem; +overflow-x: auto; +margin-bottom: 1rem; +border: 1px solid var(--border-color); +} + +.markdown-body pre code { +background: none; +padding: 0; +font-size: 0.875rem; +line-height: 1.6; +} + +.markdown-body blockquote { +border-left: 3px solid var(--accent-color); +padding-left: 1rem; +margin-bottom: 1rem; +color: var(--text-muted); +font-style: italic; +} + +.markdown-body table { +width: 100%; +border-collapse: collapse; +margin-bottom: 1rem; +} + +.markdown-body th, +.markdown-body td { +padding: 0.75rem; +border: 1px solid var(--border-color); +text-align: left; +} + +.markdown-body th { +background: var(--bg-secondary); +font-weight: 600; +color: var(--text-primary); +} + +.markdown-body tr:nth-child(even) { +background: var(--bg-secondary); +} + +.markdown-body hr { +border: none; +border-top: 1px solid var(--border-color); +margin: 2rem 0; +} + +.markdown-body img { +max-width: 100%; +height: auto; +border-radius: var(--radius); +box-shadow: var(--shadow); +} + +.markdown-body img[src*=".svg"] { +background: var(--bg-secondary); +padding: 1rem; +} + +.overlay { +display: none; +position: fixed; +top: 0; left: 0; right: 0; bottom: 0; +background: rgba(0,0,0,0.5); +z-index: 99; +} + +@media (max-width: 768px) { +.sidebar { +transform: translateX(-100%); +} + +.sidebar.open { +transform: translateX(0); +} + +.content { +margin-left: 0; +} + +.mobile-header { +display: flex; +} + +.markdown-body { +padding: 20px; +} + +.overlay.show { +display: block; +} +} + +@media (max-width: 480px) { +.markdown-body h1 { font-size: 1.5rem; } +.markdown-body h2 { font-size: 1.25rem; } +.markdown-body { padding: 16px; } +} \ No newline at end of file