ignore dist/
This commit is contained in:
parent
a3579a4ff1
commit
6b08ab4c80
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
node_modules/
|
||||
|
||||
dist/
|
||||
|
187
dist/bundle.js
vendored
187
dist/bundle.js
vendored
@ -1,187 +0,0 @@
|
||||
// src/index.ts
|
||||
async function githubTree(name, ref) {
|
||||
return {
|
||||
id: 0,
|
||||
path: "",
|
||||
filename: name,
|
||||
kind: {
|
||||
type: "dir",
|
||||
children: await githubListRecursive(name, ref)
|
||||
}
|
||||
};
|
||||
}
|
||||
async function githubListRecursive(name, ref, path = "", nextId = [1]) {
|
||||
const fileNodes = await fetch(
|
||||
`https://api.github.com/repos/${name}/contents${path}?ref=${ref}`
|
||||
).then((res) => res.json());
|
||||
return Promise.all(
|
||||
fileNodes.map(async (node) => {
|
||||
const id = nextId[0]++;
|
||||
if (node.type === "dir") {
|
||||
return await githubListRecursive(
|
||||
name,
|
||||
ref,
|
||||
`${path}/${node.name}`,
|
||||
nextId
|
||||
).then((children) => ({
|
||||
id,
|
||||
filename: node.name,
|
||||
path,
|
||||
kind: { type: "dir", children }
|
||||
}));
|
||||
} else if (node.type === "file") {
|
||||
return {
|
||||
id,
|
||||
filename: node.name,
|
||||
path,
|
||||
kind: { type: "file", url: node.download_url }
|
||||
};
|
||||
}
|
||||
throw new Error();
|
||||
})
|
||||
);
|
||||
}
|
||||
function generateTreeHtml(node) {
|
||||
return `<ul>${generateNodeHtml(node)}</ul>`;
|
||||
}
|
||||
function generateNodeHtml(node) {
|
||||
if (node.kind.type === "dir") {
|
||||
const children = node.kind.children.map((node2) => generateNodeHtml(node2)).join("");
|
||||
return `<li>
|
||||
<input type="checkbox" id="checkbox-${node.id}" checked>
|
||||
${node.filename}/
|
||||
<ul>${children}</ul>
|
||||
</li>`;
|
||||
} else if (node.kind.type === "file") {
|
||||
return `
|
||||
<li>
|
||||
<input type="checkbox" id="checkbox-${node.id}" checked>
|
||||
${node.filename}
|
||||
</li>
|
||||
`;
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
function queryHtmlINodes(tree) {
|
||||
const nodes = /* @__PURE__ */ new Map();
|
||||
queryHtmlINodesRecursive(nodes, tree);
|
||||
return nodes;
|
||||
}
|
||||
function queryHtmlINodesRecursive(nodes, node, parentId) {
|
||||
const checkbox = document.querySelector(`#checkbox-${node.id}`);
|
||||
if (node.kind.type === "dir") {
|
||||
nodes.set(node.id, { node, parentId, checkbox });
|
||||
for (const child of node.kind.children) {
|
||||
queryHtmlINodesRecursive(nodes, child, node.id);
|
||||
}
|
||||
} else if (node.kind.type === "file") {
|
||||
nodes.set(node.id, { node, parentId, checkbox });
|
||||
}
|
||||
}
|
||||
function hydrateHtmlTree(tree) {
|
||||
for (const node of tree.values()) {
|
||||
node.checkbox.addEventListener("change", () => {
|
||||
if (node.node.kind.type === "dir") {
|
||||
setCheckChildrenRecursively(
|
||||
tree,
|
||||
node.node.id,
|
||||
node.checkbox.checked
|
||||
);
|
||||
}
|
||||
checkParentDirCheckRecursively(tree, node.parentId);
|
||||
});
|
||||
}
|
||||
}
|
||||
function setCheckChildrenRecursively(tree, id, state) {
|
||||
const node = tree.get(id);
|
||||
if (node.node.kind.type !== "dir") {
|
||||
throw new Error();
|
||||
}
|
||||
for (const { id: childId } of node.node.kind.children) {
|
||||
const child = tree.get(childId);
|
||||
child.checkbox.checked = state;
|
||||
if (child.node.kind.type === "dir") {
|
||||
setCheckChildrenRecursively(tree, childId, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
function checkParentDirCheckRecursively(tree, parentId) {
|
||||
if (parentId === void 0) {
|
||||
return;
|
||||
}
|
||||
const parent = tree.get(parentId);
|
||||
if (parent === void 0) {
|
||||
throw new Error();
|
||||
}
|
||||
if (parent.node.kind.type !== "dir") {
|
||||
return;
|
||||
}
|
||||
const checked = parent.node.kind.children.some(({ id }) => tree.get(id).checkbox.checked);
|
||||
parent.checkbox.checked = checked;
|
||||
checkParentDirCheckRecursively(tree, parent.parentId);
|
||||
}
|
||||
async function* searchTree(tree, pattern) {
|
||||
for (const node of tree.values()) {
|
||||
if (node.node.kind.type !== "file") {
|
||||
continue;
|
||||
}
|
||||
if (!node.checkbox.checked) {
|
||||
continue;
|
||||
}
|
||||
const text = await fetch(node.node.kind.url).then((res) => res.text());
|
||||
const lines = text.split("\n").map((v, i) => [v, i]);
|
||||
for (const [linetext, i] of lines) {
|
||||
if (!pattern.test(linetext)) {
|
||||
continue;
|
||||
}
|
||||
const { filename, path } = node.node;
|
||||
const linenr = i + 1;
|
||||
yield { filename, path, linetext, linenr };
|
||||
}
|
||||
}
|
||||
}
|
||||
var repoNameInput = document.querySelector("#repo-name");
|
||||
var repoRefInput = document.querySelector("#repo-ref");
|
||||
var gitProviderSelect = document.querySelector("#git-provider");
|
||||
var loadRepoButton = document.querySelector("#load-repo");
|
||||
var fileTreeDiv = document.querySelector("#file-tree");
|
||||
var searchPatternInput = document.querySelector("#search-pattern");
|
||||
var searchButton = document.querySelector("#search");
|
||||
var searchStatusSpan = document.querySelector("#search-status");
|
||||
var searchResultsDiv = document.querySelector("#search-results");
|
||||
loadRepoButton.onclick = async () => {
|
||||
const name = repoNameInput.value;
|
||||
const ref = repoRefInput.value;
|
||||
const provider = gitProviderSelect.value;
|
||||
if (provider === "github") {
|
||||
const tree = await githubTree(name, ref);
|
||||
fileTreeDiv.innerHTML = generateTreeHtml(tree);
|
||||
const htmlTree = queryHtmlINodes(tree);
|
||||
hydrateHtmlTree(htmlTree);
|
||||
searchStatusSpan.innerText = ``;
|
||||
searchButton.onclick = async () => {
|
||||
const patternText = searchPatternInput.value;
|
||||
const pattern = new RegExp(patternText);
|
||||
searchStatusSpan.innerText = "Searching ...";
|
||||
searchResultsDiv.innerHTML = "";
|
||||
let matches = 0;
|
||||
for await (const match of searchTree(htmlTree, pattern)) {
|
||||
matches += 1;
|
||||
searchResultsDiv.innerHTML += `
|
||||
<div>
|
||||
<p>${match.path}/${match.filename} line ${match.linenr}</p>
|
||||
<code>${match.linetext}</code>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
if (matches === 0) {
|
||||
searchStatusSpan.innerText = "** Nothing found **";
|
||||
} else {
|
||||
searchStatusSpan.innerText = `\u22C6\u02D9\u27E1 Done, ${matches} matches \u27E1\u02D9\u22C6`;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
searchButton.onclick = () => {
|
||||
searchStatusSpan.innerText = `No repository loaded :(`;
|
||||
};
|
Loading…
Reference in New Issue
Block a user