| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>模块开发与测试指南 - Animal.js</title>
- <link rel="stylesheet" href="demo.css">
- <style>
- .md-wrap {
- background: #0e0e0e;
- border: 1px solid #1e1e1e;
- border-radius: 10px;
- overflow: hidden;
- box-shadow: 0 10px 40px rgba(0,0,0,0.25);
- }
- .md-head {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 12px;
- padding: 12px 16px;
- border-bottom: 1px solid #222;
- background: rgba(255,255,255,0.02);
- }
- .md-title {
- color: var(--orange);
- font-weight: 700;
- font-size: 13px;
- }
- .md-actions {
- display: inline-flex;
- gap: 10px;
- align-items: center;
- }
- .md-actions button {
- appearance: none;
- background: rgba(255,255,255,0.02);
- border: 1px solid #2a2a2a;
- color: #cfcfcf;
- padding: 6px 10px;
- border-radius: 999px;
- font-size: 12px;
- font-weight: 700;
- cursor: pointer;
- }
- .md-actions button:hover {
- border-color: var(--orange);
- color: var(--orange);
- }
- pre.md {
- margin: 0;
- padding: 18px 18px 22px;
- white-space: pre-wrap;
- word-break: break-word;
- line-height: 1.65;
- color: #cfcfcf;
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
- font-size: 13px;
- background: #0b0b0b;
- max-height: calc(100vh - 210px);
- overflow: auto;
- }
- .hint {
- color: #8a8a8a;
- font-size: 12px;
- margin: 0;
- padding: 0 18px 16px;
- }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="page-top">
- <div class="crumb">DEVELOPER › MODULE</div>
- <div class="since">WORKFLOW</div>
- </div>
- <h1>模块开发与测试指南</h1>
- <p class="description">
- 这个页面会直接读取 <code class="inline">doc/module.md</code> 的内容(原样显示)。<br>
- 你可以在编辑器里继续完善它,然后回来刷新这里查看最新版本。
- </p>
- <div class="md-wrap">
- <div class="md-head">
- <div class="md-title">doc/module.md</div>
- <div class="md-actions">
- <button type="button" onclick="reloadMd()">刷新</button>
- <button type="button" onclick="copyMd()">复制全文</button>
- </div>
- </div>
- <pre id="md" class="md">Loading…</pre>
- <p class="hint">提示:这是一份“开发用”总指导文档;具体示例页仍在各个模块里。</p>
- </div>
- <div class="doc-nav" aria-label="Previous and next navigation">
- <a href="#" onclick="goPrev(); return false;">
- <span>
- <span class="nav-label">Previous</span><br>
- <span id="prev-title" class="nav-title">—</span>
- </span>
- <span aria-hidden="true">←</span>
- </a>
- <div id="nav-center" class="nav-center">Developer</div>
- <a href="#" onclick="goNext(); return false;">
- <span>
- <span class="nav-label">Next</span><br>
- <span id="next-title" class="nav-title">—</span>
- </span>
- <span aria-hidden="true">→</span>
- </a>
- </div>
- </div>
- <div id="toast" class="toast" role="status" aria-live="polite"></div>
- <script>
- const CURRENT = 'module.html';
- function showToast(msg) {
- const el = document.getElementById('toast');
- if (!el) return;
- el.textContent = msg;
- el.classList.add('show');
- clearTimeout(el._t);
- el._t = setTimeout(() => el.classList.remove('show'), 900);
- }
- async function reloadMd() {
- const el = document.getElementById('md');
- if (!el) return;
- el.textContent = 'Loading…';
- try {
- const res = await fetch('module.md', { cache: 'no-store' });
- const txt = await res.text();
- el.textContent = txt || '(empty)';
- } catch (e) {
- el.textContent = 'Failed to load doc/module.md\n\n' + (e && e.message ? e.message : String(e));
- }
- syncPrevNext();
- }
- async function copyMd() {
- const el = document.getElementById('md');
- const text = el ? el.textContent : '';
- if (!text) return;
- try {
- await navigator.clipboard.writeText(text);
- showToast('Copied');
- } catch (e) {
- showToast('Copy failed');
- }
- }
- function syncPrevNext() {
- try {
- const pn = window.parent?.docGetPrevNext?.(CURRENT);
- const prevEl = document.getElementById('prev-title');
- const nextEl = document.getElementById('next-title');
- const centerEl = document.getElementById('nav-center');
- if (pn?.current && centerEl) centerEl.textContent = pn.current.group || 'Developer';
- if (prevEl) prevEl.textContent = pn?.prev?.title || '—';
- if (nextEl) nextEl.textContent = pn?.next?.title || '—';
- } catch {}
- }
- function goPrev() { window.parent?.docNavigatePrev?.(CURRENT); }
- function goNext() { window.parent?.docNavigateNext?.(CURRENT); }
- // Sync middle list selection when loaded inside doc/index.html
- try { window.parent?.setMiddleActive?.(CURRENT); } catch {}
- reloadMd();
- </script>
- </body>
- </html>
|