@gitpagedocs/cli 1.1.54 → 1.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -30
- package/builders/config-orchestrator.mjs +1 -7
- package/builders/root-config-builder.mjs +12 -9
- package/builders/route-builders.mjs +25 -0
- package/builders/theme-template.mjs +1 -1
- package/builders/version-config-builder.mjs +62 -56
- package/content/docs-en.mjs +23 -22
- package/content/docs-es.mjs +20 -19
- package/content/docs-pt.mjs +20 -19
- package/contracts/doc-versions.mjs +3 -1
- package/data/i18n-langmenu.mjs +47 -11
- package/data/path-mappings.mjs +2 -10
- package/data/route-metas.mjs +21 -1
- package/package.json +3 -3
- package/runtime/output.mjs +35 -11
- package/runtime/workflow.mjs +24 -61
- package/start.mjs +1 -1
- package/builders/source-viewer.mjs +0 -330
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
/** Generate GitHub-style source code viewer HTML from src/, cli/, and root config files */
|
|
2
|
-
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { readFileSync, readdirSync, existsSync } from "node:fs";
|
|
5
|
-
|
|
6
|
-
function buildTreeFromKeys(fileKeys) {
|
|
7
|
-
const root = {};
|
|
8
|
-
for (const key of fileKeys) {
|
|
9
|
-
const parts = key.split("/");
|
|
10
|
-
let curr = root;
|
|
11
|
-
for (let i = 0; i < parts.length; i++) {
|
|
12
|
-
const part = parts[i];
|
|
13
|
-
const isLast = i === parts.length - 1;
|
|
14
|
-
if (!curr[part]) curr[part] = isLast ? { path: key } : {};
|
|
15
|
-
if (isLast) curr[part].path = key;
|
|
16
|
-
else curr = curr[part];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return root;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const ROOT_FILES = ["README.md", "package.json", "package-lock.json", "next.config.ts", "tsconfig.json", ".eslintrc.json"];
|
|
23
|
-
|
|
24
|
-
function collectSourceFiles(projectRoot) {
|
|
25
|
-
const files = {};
|
|
26
|
-
function scan(dir, prefix = "") {
|
|
27
|
-
if (!existsSync(dir)) return;
|
|
28
|
-
const entries = readdirSync(dir, { withFileTypes: true })
|
|
29
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
30
|
-
for (const e of entries) {
|
|
31
|
-
const name = e.name;
|
|
32
|
-
if (name === "node_modules" || name.startsWith(".")) continue;
|
|
33
|
-
const rel = prefix ? `${prefix}/${name}` : name;
|
|
34
|
-
const fullPath = path.join(dir, name);
|
|
35
|
-
if (e.isDirectory()) {
|
|
36
|
-
scan(fullPath, rel);
|
|
37
|
-
} else {
|
|
38
|
-
try {
|
|
39
|
-
const content = readFileSync(fullPath, "utf-8");
|
|
40
|
-
files[rel] = content;
|
|
41
|
-
} catch {
|
|
42
|
-
/* skip binary or unreadable */
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
for (const f of ROOT_FILES) {
|
|
48
|
-
const p = path.join(projectRoot, f);
|
|
49
|
-
if (existsSync(p)) {
|
|
50
|
-
try {
|
|
51
|
-
files[f] = readFileSync(p, "utf-8");
|
|
52
|
-
} catch {}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const srcDir = path.join(projectRoot, "src");
|
|
56
|
-
const cliDir = path.join(projectRoot, "cli");
|
|
57
|
-
if (existsSync(srcDir)) scan(srcDir, "src");
|
|
58
|
-
if (existsSync(cliDir)) scan(cliDir, "cli");
|
|
59
|
-
return files;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** GitHub-like file viewer: breadcrumb bar, file header, table layout, dark theme */
|
|
63
|
-
export function generateSourceViewerHtml(root) {
|
|
64
|
-
const files = collectSourceFiles(root);
|
|
65
|
-
const fileKeys = Object.keys(files).sort();
|
|
66
|
-
const tree = buildTreeFromKeys(fileKeys);
|
|
67
|
-
const noFilesMsg = "No files found.";
|
|
68
|
-
const dataJson = JSON.stringify({ files, fileKeys, tree });
|
|
69
|
-
return `<!DOCTYPE html>
|
|
70
|
-
<html lang="en">
|
|
71
|
-
<head>
|
|
72
|
-
<meta charset="UTF-8"/>
|
|
73
|
-
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
74
|
-
<title>Source code - GitHub</title>
|
|
75
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css"/>
|
|
76
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
|
77
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"></script>
|
|
78
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/tsx.min.js"></script>
|
|
79
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"></script>
|
|
80
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/json.min.js"></script>
|
|
81
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/css.min.js"></script>
|
|
82
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/markdown.min.js"></script>
|
|
83
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script>
|
|
84
|
-
<style>
|
|
85
|
-
/* GitHub dark theme - variables */
|
|
86
|
-
:root{
|
|
87
|
-
--github-bg: #0d1117;
|
|
88
|
-
--github-bg-secondary: #161b22;
|
|
89
|
-
--github-bg-tertiary: #21262d;
|
|
90
|
-
--github-border: #30363d;
|
|
91
|
-
--github-border-muted: #21262d;
|
|
92
|
-
--github-fg: #e6edf3;
|
|
93
|
-
--github-fg-muted: #8b949e;
|
|
94
|
-
--github-accent: #58a6ff;
|
|
95
|
-
--github-accent-soft: #79c0ff;
|
|
96
|
-
}
|
|
97
|
-
*{box-sizing:border-box;margin:0;padding:0}
|
|
98
|
-
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;background:var(--github-bg);color:var(--github-fg);min-height:100vh;font-size:14px;line-height:1.5}
|
|
99
|
-
|
|
100
|
-
/* Top bar - GitHub style */
|
|
101
|
-
.top-bar{background:var(--github-bg-secondary);border-bottom:1px solid var(--github-border-muted);padding:8px 16px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
102
|
-
.top-bar .crumb{color:var(--github-fg-muted);text-decoration:none}
|
|
103
|
-
.top-bar .crumb:hover{color:var(--github-accent)}
|
|
104
|
-
.top-bar .crumb-sep{color:var(--github-fg-muted);user-select:none}
|
|
105
|
-
.top-bar .file-name{color:var(--github-fg);font-weight:600}
|
|
106
|
-
|
|
107
|
-
/* Layout */
|
|
108
|
-
.layout{display:flex;height:calc(100vh - 45px)}
|
|
109
|
-
|
|
110
|
-
/* Sidebar - GitHub file tree */
|
|
111
|
-
.sidebar{width:260px;min-width:200px;background:var(--github-bg-secondary);border-right:1px solid var(--github-border-muted);overflow-y:auto;padding:8px 0;flex-shrink:0}
|
|
112
|
-
.sidebar .folder,.sidebar .file{padding:4px 12px 4px 8px;font-size:13px;cursor:pointer;display:flex;align-items:center;gap:6px;border-radius:6px;margin:0 8px}
|
|
113
|
-
.sidebar .folder:hover,.sidebar .file:hover{background:var(--github-bg-tertiary)}
|
|
114
|
-
.sidebar .file{color:var(--github-fg-muted)}
|
|
115
|
-
.sidebar .file.active{color:var(--github-accent);background:var(--github-bg-tertiary)}
|
|
116
|
-
.sidebar .icon{width:16px;text-align:center;flex-shrink:0}
|
|
117
|
-
.sidebar .icon svg{vertical-align:middle}
|
|
118
|
-
.sidebar .folder .icon{color:var(--github-accent-soft)}
|
|
119
|
-
.sidebar .chevron{width:16px;transition:transform .15s;flex-shrink:0}
|
|
120
|
-
.sidebar .folder.collapsed .chevron{transform:rotate(-90deg)}
|
|
121
|
-
.sidebar .children{margin-left:4px}
|
|
122
|
-
.sidebar .children.hidden{display:none}
|
|
123
|
-
.sidebar .search-wrap{padding:8px;border-bottom:1px solid var(--github-border-muted)}
|
|
124
|
-
.sidebar .search-input{width:100%;padding:6px 10px;font-size:12px;border:1px solid var(--github-border);border-radius:6px;background:var(--github-bg);color:var(--github-fg);outline:none}
|
|
125
|
-
.sidebar .search-input:focus{border-color:var(--github-accent)}
|
|
126
|
-
.sidebar .search-input::placeholder{color:var(--github-fg-muted)}
|
|
127
|
-
.sidebar .tree-actions{display:flex;gap:4px;padding:4px 8px;border-bottom:1px solid var(--github-border-muted)}
|
|
128
|
-
.sidebar .tree-btn{padding:4px 8px;font-size:11px;border:1px solid var(--github-border);border-radius:4px;background:var(--github-bg-tertiary);color:var(--github-fg-muted);cursor:pointer}
|
|
129
|
-
.sidebar .tree-btn:hover{color:var(--github-fg);background:var(--github-border)}
|
|
130
|
-
|
|
131
|
-
/* Content - GitHub file view */
|
|
132
|
-
.content{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--github-bg)}
|
|
133
|
-
.content .file-header{background:var(--github-bg-secondary);border-bottom:1px solid var(--github-border-muted);padding:8px 16px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}
|
|
134
|
-
.content .file-header .file-path{font-weight:600;color:var(--github-fg)}
|
|
135
|
-
.content .file-header .copy-btn{padding:4px 12px;font-size:12px;border:1px solid var(--github-border);border-radius:6px;background:var(--github-bg-tertiary);color:var(--github-fg);cursor:pointer}
|
|
136
|
-
.content .file-header .copy-btn:hover{background:var(--github-border);border-color:var(--github-fg-muted)}
|
|
137
|
-
.content .code-wrap{flex:1;overflow:auto}
|
|
138
|
-
.content .code-table{width:100%;border-collapse:collapse;font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;font-size:12px;line-height:1.45}
|
|
139
|
-
.content .code-table td{vertical-align:top;padding:0}
|
|
140
|
-
.content .line-nums{padding:16px 0;text-align:right;user-select:none;color:var(--github-fg-muted);background:var(--github-bg-secondary);border-right:1px solid var(--github-border-muted);width:1%;min-width:50px}
|
|
141
|
-
.content .line-nums span{display:block;padding:0 16px}
|
|
142
|
-
.content .line-code{padding:16px 0;padding-left:16px}
|
|
143
|
-
.content .line-code .line{display:block;min-height:1.45em;white-space:pre}
|
|
144
|
-
.content .empty{color:var(--github-fg-muted);padding:24px;font-style:italic}
|
|
145
|
-
.content .md-preview{padding:24px;line-height:1.6}
|
|
146
|
-
.content .md-preview h1,.content .md-preview h2,.content .md-preview h3{margin-top:1em;margin-bottom:0.5em;font-weight:600}
|
|
147
|
-
.content .md-preview code{background:var(--github-bg-tertiary);padding:2px 6px;border-radius:4px;font-size:0.9em}
|
|
148
|
-
.content .md-preview pre{background:var(--github-bg-tertiary);padding:16px;overflow-x:auto;border-radius:6px;font-size:13px}
|
|
149
|
-
.content .btn-group{display:flex;gap:8px;margin-bottom:16px}
|
|
150
|
-
.content .btn{padding:6px 12px;border:1px solid var(--github-border);border-radius:6px;background:var(--github-bg-tertiary);color:var(--github-fg);cursor:pointer;font-size:12px}
|
|
151
|
-
.content .btn.active{background:var(--github-accent);border-color:var(--github-accent);color:#fff}
|
|
152
|
-
.content .btn:hover{background:var(--github-border)}
|
|
153
|
-
|
|
154
|
-
@media(max-width:767px){
|
|
155
|
-
.layout{flex-direction:column;height:auto;min-height:100vh}
|
|
156
|
-
.sidebar{width:100%;max-height:200px;border-right:none;border-bottom:1px solid var(--github-border-muted)}
|
|
157
|
-
.content .code-wrap{min-height:400px}
|
|
158
|
-
}
|
|
159
|
-
</style>
|
|
160
|
-
</head>
|
|
161
|
-
<body>
|
|
162
|
-
<div class="top-bar">
|
|
163
|
-
<span class="crumb">source</span>
|
|
164
|
-
<span class="crumb-sep">/</span>
|
|
165
|
-
<span class="file-name" id="breadcrumbFile">-</span>
|
|
166
|
-
</div>
|
|
167
|
-
<div class="layout">
|
|
168
|
-
<aside class="sidebar">
|
|
169
|
-
<div class="search-wrap"><input type="text" class="search-input" id="searchInput" placeholder="Filter files..." autocomplete="off"/></div>
|
|
170
|
-
<div class="tree-actions"><button class="tree-btn" id="expandAll">Expand all</button><button class="tree-btn" id="collapseAll">Collapse all</button></div>
|
|
171
|
-
<div id="tree"></div>
|
|
172
|
-
</aside>
|
|
173
|
-
<main class="content">
|
|
174
|
-
<div class="file-header" id="fileHeader" style="display:none">
|
|
175
|
-
<span class="file-path" id="headerPath"></span>
|
|
176
|
-
<button class="copy-btn" id="copyBtn">Copy</button>
|
|
177
|
-
</div>
|
|
178
|
-
<div class="code-wrap">
|
|
179
|
-
<pre class="content-inner" id="viewer"><code class="empty">${fileKeys.length ? "Select a file from the sidebar" : noFilesMsg}</code></pre>
|
|
180
|
-
</div>
|
|
181
|
-
</main>
|
|
182
|
-
</div>
|
|
183
|
-
<script type="application/json" id="filesData">${dataJson.replace(/<\/script>/gi, "<\\/script>")}</script>
|
|
184
|
-
<script>
|
|
185
|
-
(function(){
|
|
186
|
-
var el=document.getElementById("filesData");
|
|
187
|
-
var raw=el?el.textContent:"{}";
|
|
188
|
-
var data=JSON.parse(raw);
|
|
189
|
-
var files=data.files||{}, keys=data.fileKeys||[], treeData=data.tree||{};
|
|
190
|
-
function esc(s){var d=document.createElement("div");d.textContent=s;return d.innerHTML}
|
|
191
|
-
function getLang(p){
|
|
192
|
-
if(p.endsWith(".ts")||p.endsWith(".tsx"))return"typescript";
|
|
193
|
-
if(p.endsWith(".js")||p.endsWith(".mjs")||p.endsWith(".cjs"))return"javascript";
|
|
194
|
-
if(p.endsWith(".json"))return"json";
|
|
195
|
-
if(p.endsWith(".css"))return"css";
|
|
196
|
-
if(p.endsWith(".md"))return"markdown";
|
|
197
|
-
return"";
|
|
198
|
-
}
|
|
199
|
-
var viewMode="code";
|
|
200
|
-
function setViewMode(mode){viewMode=mode}
|
|
201
|
-
function selectFile(path){
|
|
202
|
-
document.querySelectorAll(".sidebar .file.active").forEach(function(n){n.classList.remove("active")});
|
|
203
|
-
document.querySelectorAll(".sidebar .folder.active").forEach(function(n){n.classList.remove("active")});
|
|
204
|
-
var node=document.querySelector('.sidebar .file[data-path="'+path.replace(/"/g,'\\"')+'"]');
|
|
205
|
-
if(node){node.classList.add("active");node.scrollIntoView({block:"nearest"})}
|
|
206
|
-
document.getElementById("breadcrumbFile").textContent=path;
|
|
207
|
-
document.getElementById("fileHeader").style.display="block";
|
|
208
|
-
document.getElementById("headerPath").textContent=path;
|
|
209
|
-
var content=files[path]||"";
|
|
210
|
-
var isReadme=path.toLowerCase()==="readme.md";
|
|
211
|
-
var viewer=document.getElementById("viewer");
|
|
212
|
-
if(isReadme){
|
|
213
|
-
var btnHtml='<div class="btn-group"><button class="btn'+(viewMode==='preview'?' active':'')+'" data-mode="preview">Preview</button><button class="btn'+(viewMode==='code'?' active':'')+'" data-mode="code">Code</button></div>';
|
|
214
|
-
if(viewMode==="preview"&&typeof marked!=="undefined"){
|
|
215
|
-
viewer.innerHTML=btnHtml+'<div class="md-preview">'+marked.parse(content||"")+'</div>';
|
|
216
|
-
}else{
|
|
217
|
-
var lines=(content||"").split("\\n");
|
|
218
|
-
var lineHtml="";
|
|
219
|
-
lines.forEach(function(line,i){lineHtml+="<span class=\\"line-num\\">"+(i+1)+"</span><span class=\\"line\\">"+esc(line)+"\\n</span>"});
|
|
220
|
-
viewer.innerHTML=btnHtml+"<code>"+lineHtml+"</code>";
|
|
221
|
-
if(typeof hljs!=="undefined"){var c=viewer.querySelector("code");if(c){c.className="language-markdown";hljs.highlightElement(c)}}
|
|
222
|
-
}
|
|
223
|
-
viewer.classList.remove("empty");
|
|
224
|
-
viewer.querySelectorAll(".btn").forEach(function(btn){
|
|
225
|
-
btn.onclick=function(){setViewMode(btn.dataset.mode);selectFile(path)};
|
|
226
|
-
});
|
|
227
|
-
}else{
|
|
228
|
-
var lines=content.split("\\n");
|
|
229
|
-
var nums="",code="";
|
|
230
|
-
lines.forEach(function(line,i){nums+="<span>"+(i+1)+"</span>";code+="<span class=\\"line\\">"+esc(line)+"\\n</span>"});
|
|
231
|
-
viewer.innerHTML='<table class="code-table"><tr><td class="line-nums">'+nums+'</td><td class="line-code"><code>'+code+'</code></td></tr></table>';
|
|
232
|
-
viewer.classList.remove("empty");
|
|
233
|
-
var c=viewer.querySelector("code");if(c&&typeof hljs!=="undefined"){c.className="language-"+getLang(path);hljs.highlightElement(c)}
|
|
234
|
-
}
|
|
235
|
-
window._currentPath=path;window._currentContent=content;
|
|
236
|
-
}
|
|
237
|
-
document.getElementById("copyBtn").onclick=function(){
|
|
238
|
-
var p=window._currentPath,c=window._currentContent;
|
|
239
|
-
if(!c)return;
|
|
240
|
-
navigator.clipboard&&navigator.clipboard.writeText(c).then(function(){var b=document.getElementById("copyBtn");var t=b.textContent;b.textContent="Copied!";setTimeout(function(){b.textContent=t},1500)});
|
|
241
|
-
};
|
|
242
|
-
function folderIcon(){return'<svg width="16" height="16" viewBox="0 0 16 16"><path fill="currentColor" d="M.513 1.513A1.75 1.75 0 0 1 1.75 1h3.5c.58 0 1.165.224 1.587.624l.357.364A.75.75 0 0 0 8 2h5.25A1.75 1.75 0 0 1 15 3.75v8.5A1.75 1.75 0 0 1 13.25 14H1.75A1.75 1.75 0 0 1 0 12.25v-9.5C0 2.178.78 1.408 1.513 1.513Z"/></svg>'}
|
|
243
|
-
function fileIcon(){return'<svg width="16" height="16" viewBox="0 0 16 16"><path fill="currentColor" d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Z"/></svg>'}
|
|
244
|
-
function chevronDown(){return'<svg width="16" height="16" viewBox="0 0 16 16"><path fill="currentColor" d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z"/></svg>'}
|
|
245
|
-
function renderTree(node, parentEl, indent){
|
|
246
|
-
indent=indent||0;
|
|
247
|
-
var keys=Object.keys(node).sort();
|
|
248
|
-
for(var i=0;i<keys.length;i++){
|
|
249
|
-
var k=keys[i];
|
|
250
|
-
var v=node[k];
|
|
251
|
-
if(k==="path")continue;
|
|
252
|
-
if(v&&typeof v==="object"&&v.path){
|
|
253
|
-
var div=document.createElement("div");
|
|
254
|
-
div.className="file";
|
|
255
|
-
div.dataset.path=v.path;
|
|
256
|
-
div.style.marginLeft=(indent*12)+"px";
|
|
257
|
-
div.innerHTML='<span class="icon">'+fileIcon()+'</span>'+esc(k);
|
|
258
|
-
div.onclick=function(p){return function(){selectFile(p)}}(v.path);
|
|
259
|
-
parentEl.appendChild(div);
|
|
260
|
-
}else if(v&&typeof v==="object"){
|
|
261
|
-
var folderDiv=document.createElement("div");
|
|
262
|
-
folderDiv.className="folder";
|
|
263
|
-
folderDiv.style.marginLeft=(indent*12)+"px";
|
|
264
|
-
folderDiv.innerHTML='<span class="chevron">'+chevronDown()+'</span><span class="icon">'+folderIcon()+'</span>'+esc(k);
|
|
265
|
-
var children=document.createElement("div");
|
|
266
|
-
children.className="children";
|
|
267
|
-
folderDiv.onclick=function(e){
|
|
268
|
-
if(e.target.closest(".file"))return;
|
|
269
|
-
var self=e.currentTarget;
|
|
270
|
-
self.classList.toggle("collapsed");
|
|
271
|
-
children.classList.toggle("hidden",self.classList.contains("collapsed"));
|
|
272
|
-
};
|
|
273
|
-
parentEl.appendChild(folderDiv);
|
|
274
|
-
parentEl.appendChild(children);
|
|
275
|
-
renderTree(v,children,indent+1);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
function buildTreeFromKeys(keys){
|
|
280
|
-
var root={};
|
|
281
|
-
keys.forEach(function(key){
|
|
282
|
-
var parts=key.split("/");
|
|
283
|
-
var curr=root;
|
|
284
|
-
for(var i=0;i<parts.length;i++){
|
|
285
|
-
var part=parts[i];
|
|
286
|
-
var isLast=i===parts.length-1;
|
|
287
|
-
if(!curr[part])curr[part]=isLast?{path:key}:{};
|
|
288
|
-
if(isLast)curr[part].path=key;
|
|
289
|
-
else curr=curr[part];
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
return root;
|
|
293
|
-
}
|
|
294
|
-
function buildTree(filterQuery){
|
|
295
|
-
var treeEl=document.getElementById("tree");
|
|
296
|
-
treeEl.innerHTML="";
|
|
297
|
-
var filteredKeys=filterQuery?keys.filter(function(k){return k.toLowerCase().indexOf(filterQuery.toLowerCase())>=0;}):keys;
|
|
298
|
-
var data=filteredKeys.length?buildTreeFromKeys(filteredKeys):{};
|
|
299
|
-
if(Object.keys(data).length>0){
|
|
300
|
-
renderTree(data,treeEl,0);
|
|
301
|
-
}else{
|
|
302
|
-
filteredKeys.sort();
|
|
303
|
-
filteredKeys.forEach(function(k){
|
|
304
|
-
var div=document.createElement("div");
|
|
305
|
-
div.className="file";
|
|
306
|
-
div.dataset.path=k;
|
|
307
|
-
div.innerHTML='<span class="icon">'+fileIcon()+'</span>'+esc(k.split("/").pop());
|
|
308
|
-
div.onclick=function(){selectFile(k)};
|
|
309
|
-
treeEl.appendChild(div);
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
document.getElementById("searchInput").oninput=function(){
|
|
314
|
-
var q=this.value.trim();
|
|
315
|
-
buildTree(q);
|
|
316
|
-
};
|
|
317
|
-
document.getElementById("expandAll").onclick=function(){
|
|
318
|
-
document.querySelectorAll(".sidebar .folder.collapsed").forEach(function(f){f.classList.remove("collapsed")});
|
|
319
|
-
document.querySelectorAll(".sidebar .children.hidden").forEach(function(c){c.classList.remove("hidden")});
|
|
320
|
-
};
|
|
321
|
-
document.getElementById("collapseAll").onclick=function(){
|
|
322
|
-
document.querySelectorAll(".sidebar .folder").forEach(function(f){f.classList.add("collapsed")});
|
|
323
|
-
document.querySelectorAll(".sidebar .children").forEach(function(c){c.classList.add("hidden")});
|
|
324
|
-
};
|
|
325
|
-
buildTree();
|
|
326
|
-
})();
|
|
327
|
-
</script>
|
|
328
|
-
</body>
|
|
329
|
-
</html>`;
|
|
330
|
-
}
|