@youtyan/code-viewer 0.1.18 → 0.1.20
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/dist/code-viewer.js +190 -25
- package/package.json +3 -3
- package/web/app.js +352 -166
- package/web/style.css +19 -6
package/web/app.js
CHANGED
|
@@ -274,7 +274,7 @@
|
|
|
274
274
|
const basename = lowerPath.slice(baseStart);
|
|
275
275
|
if (basename.startsWith(q))
|
|
276
276
|
score += 30;
|
|
277
|
-
if (basename === q || basename.startsWith(q
|
|
277
|
+
if (basename === q || basename.startsWith(`${q}.`))
|
|
278
278
|
score += 25;
|
|
279
279
|
if (lowerPath.endsWith(q))
|
|
280
280
|
score += 15;
|
|
@@ -290,7 +290,7 @@
|
|
|
290
290
|
return /[*?]/.test(query.trim());
|
|
291
291
|
}
|
|
292
292
|
function escapeRegexChar(ch) {
|
|
293
|
-
return /[\\^$+?.()|{}]/.test(ch) ?
|
|
293
|
+
return /[\\^$+?.()|{}]/.test(ch) ? `\\${ch}` : ch;
|
|
294
294
|
}
|
|
295
295
|
function globToRegExp(query) {
|
|
296
296
|
const pattern = query.trim();
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
source += "\\[";
|
|
315
315
|
} else {
|
|
316
316
|
const body = pattern.slice(i + 1, close).replace(/\\/g, "\\\\");
|
|
317
|
-
source +=
|
|
317
|
+
source += `[${body}]`;
|
|
318
318
|
i = close;
|
|
319
319
|
}
|
|
320
320
|
} else {
|
|
@@ -359,22 +359,58 @@
|
|
|
359
359
|
if (isGlobPathQuery(query)) {
|
|
360
360
|
return items.map((item) => {
|
|
361
361
|
const match = globMatchPath(query, item.path);
|
|
362
|
-
return match ? {
|
|
362
|
+
return match ? {
|
|
363
|
+
item,
|
|
364
|
+
score: match.score,
|
|
365
|
+
ranges: match.ranges,
|
|
366
|
+
mode: "glob"
|
|
367
|
+
} : null;
|
|
363
368
|
}).filter((item) => item !== null).sort((a, b) => b.score - a.score || a.item.path.localeCompare(b.item.path));
|
|
364
369
|
}
|
|
365
|
-
return rankFuzzyPaths(query, items).map((item) => ({
|
|
370
|
+
return rankFuzzyPaths(query, items).map((item) => ({
|
|
371
|
+
...item,
|
|
372
|
+
mode: "fuzzy"
|
|
373
|
+
}));
|
|
366
374
|
}
|
|
367
375
|
|
|
368
376
|
// web-src/keymap.ts
|
|
369
377
|
var DEFAULT_KEY_BINDINGS = [
|
|
370
|
-
{
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
378
|
+
{
|
|
379
|
+
action: "open-file-palette",
|
|
380
|
+
key: "k",
|
|
381
|
+
ctrl: true,
|
|
382
|
+
allowEditable: true,
|
|
383
|
+
allowPaletteOpen: true
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
action: "open-file-palette",
|
|
387
|
+
key: "k",
|
|
388
|
+
meta: true,
|
|
389
|
+
allowEditable: true,
|
|
390
|
+
allowPaletteOpen: true
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
action: "open-grep-palette",
|
|
394
|
+
key: "g",
|
|
395
|
+
ctrl: true,
|
|
396
|
+
allowEditable: true,
|
|
397
|
+
allowPaletteOpen: true
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
action: "open-grep-palette",
|
|
401
|
+
key: "g",
|
|
402
|
+
meta: true,
|
|
403
|
+
allowEditable: true,
|
|
404
|
+
allowPaletteOpen: true
|
|
405
|
+
},
|
|
374
406
|
{ action: "focus-file-filter", key: "/" },
|
|
375
407
|
{ action: "focus-sidebar", key: "h", ctrl: true },
|
|
376
408
|
{ action: "focus-main", key: "l", ctrl: true },
|
|
377
|
-
{
|
|
409
|
+
{
|
|
410
|
+
action: "cancel-source-load",
|
|
411
|
+
key: "escape",
|
|
412
|
+
requires: { lightboxClosed: true }
|
|
413
|
+
},
|
|
378
414
|
{ action: "open-sidebar-item", key: "enter", scope: "sidebar" },
|
|
379
415
|
{ action: "open-sidebar-item", key: "enter", scope: "global" },
|
|
380
416
|
{ action: "sidebar-next", key: "j", scope: "sidebar" },
|
|
@@ -399,12 +435,37 @@
|
|
|
399
435
|
{ action: "scroll-main-page-up", key: "pageup", scope: "global" },
|
|
400
436
|
{ action: "scroll-main-page-down", key: "pagedown", scope: "sidebar" },
|
|
401
437
|
{ action: "scroll-main-page-up", key: "pageup", scope: "sidebar" },
|
|
402
|
-
{
|
|
438
|
+
{
|
|
439
|
+
action: "scroll-main-page-down",
|
|
440
|
+
key: "arrowdown",
|
|
441
|
+
scope: "main",
|
|
442
|
+
ctrl: true
|
|
443
|
+
},
|
|
403
444
|
{ action: "scroll-main-page-up", key: "arrowup", scope: "main", ctrl: true },
|
|
404
|
-
{
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
445
|
+
{
|
|
446
|
+
action: "scroll-main-page-down",
|
|
447
|
+
key: "arrowdown",
|
|
448
|
+
scope: "global",
|
|
449
|
+
ctrl: true
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
action: "scroll-main-page-up",
|
|
453
|
+
key: "arrowup",
|
|
454
|
+
scope: "global",
|
|
455
|
+
ctrl: true
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
action: "scroll-main-page-down",
|
|
459
|
+
key: "arrowdown",
|
|
460
|
+
scope: "sidebar",
|
|
461
|
+
ctrl: true
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
action: "scroll-main-page-up",
|
|
465
|
+
key: "arrowup",
|
|
466
|
+
scope: "sidebar",
|
|
467
|
+
ctrl: true
|
|
468
|
+
},
|
|
408
469
|
{ action: "tab-preview", key: "p", scope: "main", pendingG: true },
|
|
409
470
|
{ action: "tab-code", key: "c", scope: "main", pendingG: true },
|
|
410
471
|
{ action: "goto-top", key: "g", pendingG: true },
|
|
@@ -6031,7 +6092,7 @@
|
|
|
6031
6092
|
|
|
6032
6093
|
// web-src/routes.ts
|
|
6033
6094
|
function assertNever(value) {
|
|
6034
|
-
throw new Error(
|
|
6095
|
+
throw new Error(`unhandled route: ${JSON.stringify(value)}`);
|
|
6035
6096
|
}
|
|
6036
6097
|
function parseLegacyRange(value, fallback) {
|
|
6037
6098
|
const raw = value || "";
|
|
@@ -6059,7 +6120,7 @@
|
|
|
6059
6120
|
return Number.isInteger(line) && line > 0 ? line : undefined;
|
|
6060
6121
|
}
|
|
6061
6122
|
function formatLineTarget(line) {
|
|
6062
|
-
return typeof line === "number" ? String(line) : line.start
|
|
6123
|
+
return typeof line === "number" ? String(line) : `${line.start}-${line.end}`;
|
|
6063
6124
|
}
|
|
6064
6125
|
function parseRoute(pathname, search, fallbackRange) {
|
|
6065
6126
|
const params = new URLSearchParams(search);
|
|
@@ -6091,8 +6152,21 @@
|
|
|
6091
6152
|
const ref = target || params.get("ref") || "worktree";
|
|
6092
6153
|
const line = parseLineTarget(params.get("line"));
|
|
6093
6154
|
if (!path)
|
|
6094
|
-
return {
|
|
6095
|
-
|
|
6155
|
+
return {
|
|
6156
|
+
screen: "unknown",
|
|
6157
|
+
reason: "missing-path",
|
|
6158
|
+
rawPathname: pathname,
|
|
6159
|
+
rawSearch: search,
|
|
6160
|
+
range
|
|
6161
|
+
};
|
|
6162
|
+
return {
|
|
6163
|
+
screen: "file",
|
|
6164
|
+
path,
|
|
6165
|
+
ref,
|
|
6166
|
+
range,
|
|
6167
|
+
view: target ? "blob" : "detail",
|
|
6168
|
+
...line ? { line } : {}
|
|
6169
|
+
};
|
|
6096
6170
|
}
|
|
6097
6171
|
case "/help":
|
|
6098
6172
|
return {
|
|
@@ -6102,7 +6176,13 @@
|
|
|
6102
6176
|
section: params.get("section") || "keybindings"
|
|
6103
6177
|
};
|
|
6104
6178
|
default:
|
|
6105
|
-
return {
|
|
6179
|
+
return {
|
|
6180
|
+
screen: "unknown",
|
|
6181
|
+
reason: "unknown-pathname",
|
|
6182
|
+
rawPathname: pathname,
|
|
6183
|
+
rawSearch: search,
|
|
6184
|
+
range
|
|
6185
|
+
};
|
|
6106
6186
|
}
|
|
6107
6187
|
}
|
|
6108
6188
|
function buildRoute(route) {
|
|
@@ -6114,15 +6194,15 @@
|
|
|
6114
6194
|
if (route.path)
|
|
6115
6195
|
params.set("path", route.path);
|
|
6116
6196
|
const qs = params.toString();
|
|
6117
|
-
return
|
|
6197
|
+
return `/${qs ? `?${qs}` : ""}`;
|
|
6118
6198
|
}
|
|
6119
6199
|
case "file":
|
|
6120
6200
|
if (route.view === "blob") {
|
|
6121
|
-
return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ?
|
|
6201
|
+
return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
|
|
6122
6202
|
}
|
|
6123
|
-
return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ?
|
|
6203
|
+
return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
|
|
6124
6204
|
case "diff":
|
|
6125
|
-
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ?
|
|
6205
|
+
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? `&path=${encodeURIComponent(route.path)}` : "") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
|
|
6126
6206
|
case "help": {
|
|
6127
6207
|
const params = new URLSearchParams;
|
|
6128
6208
|
if (route.lang && route.lang !== "en")
|
|
@@ -6130,7 +6210,7 @@
|
|
|
6130
6210
|
if (route.section && route.section !== "keybindings")
|
|
6131
6211
|
params.set("section", route.section);
|
|
6132
6212
|
const qs = params.toString();
|
|
6133
|
-
return
|
|
6213
|
+
return `/help${qs ? `?${qs}` : ""}`;
|
|
6134
6214
|
}
|
|
6135
6215
|
case "unknown":
|
|
6136
6216
|
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
|
|
@@ -6218,7 +6298,10 @@
|
|
|
6218
6298
|
}
|
|
6219
6299
|
function resolveRepoRelative(currentPath, requestedPath) {
|
|
6220
6300
|
const base2 = currentPath.split("/").slice(0, -1);
|
|
6221
|
-
const parts = [
|
|
6301
|
+
const parts = [
|
|
6302
|
+
...requestedPath.startsWith("/") ? [] : base2,
|
|
6303
|
+
...requestedPath.split("/")
|
|
6304
|
+
].filter((part) => part && part !== ".");
|
|
6222
6305
|
const resolved = [];
|
|
6223
6306
|
for (const part of parts) {
|
|
6224
6307
|
if (part === "..") {
|
|
@@ -6248,7 +6331,7 @@
|
|
|
6248
6331
|
});
|
|
6249
6332
|
} catch {}
|
|
6250
6333
|
}
|
|
6251
|
-
return
|
|
6334
|
+
return `<pre><code>${md.utils.escapeHtml(code2)}</code></pre>`;
|
|
6252
6335
|
}
|
|
6253
6336
|
});
|
|
6254
6337
|
md.use(b, {
|
|
@@ -6348,7 +6431,10 @@
|
|
|
6348
6431
|
const frontmatter = splitYamlFrontmatter(textValue);
|
|
6349
6432
|
if (!frontmatter)
|
|
6350
6433
|
return md.render(textValue);
|
|
6351
|
-
return '<div class="gdp-markdown-frontmatter" data-gdp-frontmatter="yaml">' + md.render(
|
|
6434
|
+
return '<div class="gdp-markdown-frontmatter" data-gdp-frontmatter="yaml">' + md.render(`\`\`\`yaml
|
|
6435
|
+
${frontmatter.yaml}
|
|
6436
|
+
\`\`\`
|
|
6437
|
+
`) + "</div>" + md.render(frontmatter.body);
|
|
6352
6438
|
}
|
|
6353
6439
|
function splitYamlFrontmatter(textValue) {
|
|
6354
6440
|
if (!textValue.startsWith(`---
|
|
@@ -6360,7 +6446,7 @@
|
|
|
6360
6446
|
` : `
|
|
6361
6447
|
`;
|
|
6362
6448
|
const start = 3 + newline2.length;
|
|
6363
|
-
const closing = textValue.indexOf(newline2
|
|
6449
|
+
const closing = textValue.indexOf(`${newline2}---${newline2}`, start);
|
|
6364
6450
|
if (closing < 0)
|
|
6365
6451
|
return null;
|
|
6366
6452
|
return {
|
|
@@ -6409,9 +6495,9 @@
|
|
|
6409
6495
|
const list2 = document.createElement("ul");
|
|
6410
6496
|
entries.forEach((entry) => {
|
|
6411
6497
|
const item = document.createElement("li");
|
|
6412
|
-
item.className =
|
|
6498
|
+
item.className = `level-${entry.level}`;
|
|
6413
6499
|
const link2 = document.createElement("a");
|
|
6414
|
-
link2.href =
|
|
6500
|
+
link2.href = `#${encodeURIComponent(entry.id)}`;
|
|
6415
6501
|
link2.dataset.target = entry.id;
|
|
6416
6502
|
link2.textContent = entry.text;
|
|
6417
6503
|
item.appendChild(link2);
|
|
@@ -6440,19 +6526,22 @@
|
|
|
6440
6526
|
const toc = root.querySelector(".gdp-markdown-toc");
|
|
6441
6527
|
if (!toc)
|
|
6442
6528
|
return;
|
|
6443
|
-
const entries = Array.from(toc.querySelectorAll("a[data-target]")).map((link2) => ({
|
|
6529
|
+
const entries = Array.from(toc.querySelectorAll("a[data-target]")).map((link2) => ({
|
|
6530
|
+
link: link2,
|
|
6531
|
+
target: root.querySelector(`#${CSS.escape(link2.dataset.target || "")}`)
|
|
6532
|
+
})).filter((entry) => !!entry.target);
|
|
6444
6533
|
if (!entries.length)
|
|
6445
6534
|
return;
|
|
6446
6535
|
toc.addEventListener("click", (e2) => {
|
|
6447
6536
|
const link2 = e2.target?.closest("a[data-target]");
|
|
6448
6537
|
if (!link2)
|
|
6449
6538
|
return;
|
|
6450
|
-
const section = root.querySelector(
|
|
6539
|
+
const section = root.querySelector(`#${CSS.escape(link2.dataset.target || "")}`);
|
|
6451
6540
|
if (!section)
|
|
6452
6541
|
return;
|
|
6453
6542
|
e2.preventDefault();
|
|
6454
6543
|
section.scrollIntoView({ block: "start", behavior: "smooth" });
|
|
6455
|
-
history.replaceState(history.state, "",
|
|
6544
|
+
history.replaceState(history.state, "", `#${encodeURIComponent(section.id)}`);
|
|
6456
6545
|
});
|
|
6457
6546
|
const controller = new AbortController;
|
|
6458
6547
|
const scrollRoot = document.scrollingElement || document.documentElement;
|
|
@@ -6478,14 +6567,19 @@
|
|
|
6478
6567
|
if (window.innerHeight + scrollRoot.scrollTop >= scrollRoot.scrollHeight - 4) {
|
|
6479
6568
|
active = entries[entries.length - 1];
|
|
6480
6569
|
}
|
|
6481
|
-
entries.forEach((entry) =>
|
|
6570
|
+
entries.forEach((entry) => {
|
|
6571
|
+
entry.link.classList.toggle("active", entry === active);
|
|
6572
|
+
});
|
|
6482
6573
|
keepTocLinkVisible(toc, active.link);
|
|
6483
6574
|
};
|
|
6484
6575
|
const schedule = () => {
|
|
6485
6576
|
if (!raf)
|
|
6486
6577
|
raf = requestAnimationFrame(update);
|
|
6487
6578
|
};
|
|
6488
|
-
window.addEventListener("scroll", schedule, {
|
|
6579
|
+
window.addEventListener("scroll", schedule, {
|
|
6580
|
+
passive: true,
|
|
6581
|
+
signal: controller.signal
|
|
6582
|
+
});
|
|
6489
6583
|
window.addEventListener("resize", schedule, { signal: controller.signal });
|
|
6490
6584
|
setTimeout(() => {
|
|
6491
6585
|
if (!root.isConnected)
|
|
@@ -6537,7 +6631,11 @@
|
|
|
6537
6631
|
const typed = mod;
|
|
6538
6632
|
const mermaid = typed.default;
|
|
6539
6633
|
if (!mermaidInitialized) {
|
|
6540
|
-
mermaid.initialize({
|
|
6634
|
+
mermaid.initialize({
|
|
6635
|
+
startOnLoad: false,
|
|
6636
|
+
securityLevel: "strict",
|
|
6637
|
+
theme: "default"
|
|
6638
|
+
});
|
|
6541
6639
|
mermaidInitialized = true;
|
|
6542
6640
|
}
|
|
6543
6641
|
return mermaid;
|
|
@@ -6605,7 +6703,7 @@
|
|
|
6605
6703
|
let tx = 0;
|
|
6606
6704
|
let ty = 0;
|
|
6607
6705
|
const apply = () => {
|
|
6608
|
-
svg.style.transform =
|
|
6706
|
+
svg.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
|
|
6609
6707
|
};
|
|
6610
6708
|
const fit = () => {
|
|
6611
6709
|
const vw = Math.max(1, window.innerWidth - 128);
|
|
@@ -6705,7 +6803,7 @@
|
|
|
6705
6803
|
try {
|
|
6706
6804
|
const box = svg.getBBox();
|
|
6707
6805
|
if (box.width > 0 && box.height > 0) {
|
|
6708
|
-
svg.setAttribute("viewBox", box.x
|
|
6806
|
+
svg.setAttribute("viewBox", `${box.x} ${box.y} ${box.width} ${box.height}`);
|
|
6709
6807
|
svg.setAttribute("width", String(box.width));
|
|
6710
6808
|
svg.setAttribute("height", String(box.height));
|
|
6711
6809
|
return { width: box.width, height: box.height };
|
|
@@ -6947,7 +7045,7 @@
|
|
|
6947
7045
|
return Array.from(document.querySelectorAll("#content .gdp-source-virtual-scroller, #content .gdp-source-table")).some((item) => item.offsetParent !== null);
|
|
6948
7046
|
}
|
|
6949
7047
|
function sourceCursorKey(target) {
|
|
6950
|
-
return target.ref
|
|
7048
|
+
return `${target.ref}\x00${target.path}`;
|
|
6951
7049
|
}
|
|
6952
7050
|
function sourceCursorMatches(target, line) {
|
|
6953
7051
|
return !!SOURCE_CURSOR && sourceTargetsEqual(SOURCE_CURSOR.target, target) && SOURCE_CURSOR.line === line;
|
|
@@ -7002,7 +7100,7 @@
|
|
|
7002
7100
|
syncSourceCursorRows(cursor.target);
|
|
7003
7101
|
return;
|
|
7004
7102
|
}
|
|
7005
|
-
document.querySelector(
|
|
7103
|
+
document.querySelector(`#content [data-line="${cursor.line}"]`)?.scrollIntoView({ block: edge });
|
|
7006
7104
|
}
|
|
7007
7105
|
function moveSourceCursor(direction, unit, edge) {
|
|
7008
7106
|
if (!hasVisibleSourceCodeSurface())
|
|
@@ -7082,7 +7180,7 @@
|
|
|
7082
7180
|
const tabs = document.querySelector("#content .gdp-source-tabs");
|
|
7083
7181
|
if (!tabs)
|
|
7084
7182
|
return false;
|
|
7085
|
-
const button = tabs.querySelector(
|
|
7183
|
+
const button = tabs.querySelector(`button[data-source-tab="${tab}"]`);
|
|
7086
7184
|
if (!button || button.hidden || button.disabled)
|
|
7087
7185
|
return false;
|
|
7088
7186
|
button.click();
|
|
@@ -7112,7 +7210,7 @@
|
|
|
7112
7210
|
if (!project)
|
|
7113
7211
|
return;
|
|
7114
7212
|
PROJECT_NAME = project;
|
|
7115
|
-
document.title = project
|
|
7213
|
+
document.title = `${project} - code viewer`;
|
|
7116
7214
|
}
|
|
7117
7215
|
function savedScopeOmitDirs() {
|
|
7118
7216
|
const raw = localStorage.getItem(scopeOmitDirsStorageKey());
|
|
@@ -7155,7 +7253,7 @@
|
|
|
7155
7253
|
requestAnimationFrame(() => {
|
|
7156
7254
|
const head = document.querySelector(".sb-head");
|
|
7157
7255
|
if (head)
|
|
7158
|
-
document.documentElement.style.setProperty("--sidebar-head-h", Math.ceil(head.getBoundingClientRect().height)
|
|
7256
|
+
document.documentElement.style.setProperty("--sidebar-head-h", `${Math.ceil(head.getBoundingClientRect().height)}px`);
|
|
7159
7257
|
});
|
|
7160
7258
|
}
|
|
7161
7259
|
function observeSidebarHeaderHeight() {
|
|
@@ -7200,7 +7298,7 @@
|
|
|
7200
7298
|
layout: localStorage.getItem("gdp:layout") || "side-by-side",
|
|
7201
7299
|
theme: localStorage.getItem("gdp:theme") || (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"),
|
|
7202
7300
|
sbView: localStorage.getItem("gdp:sbview") || "tree",
|
|
7203
|
-
sbWidth: parseInt(localStorage.getItem("gdp:sbwidth")) || 308,
|
|
7301
|
+
sbWidth: parseInt(localStorage.getItem("gdp:sbwidth") ?? "", 10) || 308,
|
|
7204
7302
|
sidebarHidden: localStorage.getItem("gdp:sidebar-hidden") === "1",
|
|
7205
7303
|
collapsedDirs: new Set(JSON.parse(localStorage.getItem("gdp:collapsed-dirs") || "[]")),
|
|
7206
7304
|
ignoreWs: igRaw === null ? true : igRaw === "1",
|
|
@@ -7228,7 +7326,7 @@
|
|
|
7228
7326
|
$("#hljs-dark").disabled = STATE.theme !== "dark";
|
|
7229
7327
|
}
|
|
7230
7328
|
function getHljs() {
|
|
7231
|
-
const hljsRef = window.hljs || window.Diff2HtmlUI
|
|
7329
|
+
const hljsRef = window.hljs || window.Diff2HtmlUI?.hljs;
|
|
7232
7330
|
if (!hljsRef)
|
|
7233
7331
|
return null;
|
|
7234
7332
|
if (!highlightConfigured && typeof hljsRef.configure === "function") {
|
|
@@ -7409,7 +7507,7 @@
|
|
|
7409
7507
|
function fileBadge(status) {
|
|
7410
7508
|
const ch = (status || "M")[0].toUpperCase();
|
|
7411
7509
|
const span = document.createElement("span");
|
|
7412
|
-
span.className =
|
|
7510
|
+
span.className = `badge ${ch}`;
|
|
7413
7511
|
span.textContent = ch;
|
|
7414
7512
|
span.title = { M: "modified", A: "added", D: "deleted", R: "renamed" }[ch] || ch;
|
|
7415
7513
|
return span;
|
|
@@ -7449,7 +7547,7 @@
|
|
|
7449
7547
|
}
|
|
7450
7548
|
function iconSvg(className, paths) {
|
|
7451
7549
|
const pathList = Array.isArray(paths) ? paths : [paths];
|
|
7452
|
-
return '<svg class="octicon ' + className + '" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">' + pathList.map((path) =>
|
|
7550
|
+
return '<svg class="octicon ' + className + '" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true">' + pathList.map((path) => `<path fill="currentColor" d="${path}"></path>`).join("") + "</svg>";
|
|
7453
7551
|
}
|
|
7454
7552
|
function setUnfoldButtonState(button, expanded) {
|
|
7455
7553
|
if (!button)
|
|
@@ -7579,7 +7677,7 @@
|
|
|
7579
7677
|
const dirPartCount = f2.type === "tree" ? parts.length : parts.length - 1;
|
|
7580
7678
|
for (let i2 = 0;i2 < dirPartCount; i2++) {
|
|
7581
7679
|
const p2 = parts[i2];
|
|
7582
|
-
acc = acc ? acc
|
|
7680
|
+
acc = acc ? `${acc}/${p2}` : p2;
|
|
7583
7681
|
if (!node.dirs[p2]) {
|
|
7584
7682
|
node.dirs[p2] = {
|
|
7585
7683
|
name: p2,
|
|
@@ -7607,13 +7705,15 @@
|
|
|
7607
7705
|
const ks = Object.keys(node.dirs);
|
|
7608
7706
|
while (ks.length === 1 && node.files.length === 0 && !node.explicit && node !== root) {
|
|
7609
7707
|
const only = node.dirs[ks[0]];
|
|
7610
|
-
node.name = node.name ? node.name
|
|
7708
|
+
node.name = node.name ? `${node.name}/${only.name}` : only.name;
|
|
7611
7709
|
node.dirs = only.dirs;
|
|
7612
7710
|
node.files = only.files;
|
|
7613
7711
|
node.path = only.path;
|
|
7614
7712
|
node.minOrder = Math.min(node.minOrder, only.minOrder);
|
|
7615
7713
|
ks.length = 0;
|
|
7616
|
-
Object.keys(node.dirs).forEach((k) =>
|
|
7714
|
+
Object.keys(node.dirs).forEach((k) => {
|
|
7715
|
+
ks.push(k);
|
|
7716
|
+
});
|
|
7617
7717
|
}
|
|
7618
7718
|
Object.values(node.dirs).forEach(compress);
|
|
7619
7719
|
}
|
|
@@ -7648,7 +7748,7 @@
|
|
|
7648
7748
|
li.classList.add(dir.children_omitted_reason === "heavy" ? "children-omitted-heavy" : "children-omitted-internal");
|
|
7649
7749
|
li.title = dir.children_omitted_reason === "heavy" ? "Large generated/vendor directory: open the detail pane to browse its contents" : "Internal Git metadata is not browsed";
|
|
7650
7750
|
}
|
|
7651
|
-
li.style.setProperty("--lvl-pad", 12 + depth * 14
|
|
7751
|
+
li.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
|
|
7652
7752
|
const chev = document.createElement("span");
|
|
7653
7753
|
if (dir.children_omitted) {
|
|
7654
7754
|
chev.className = "chev-spacer";
|
|
@@ -7727,7 +7827,7 @@
|
|
|
7727
7827
|
li.tabIndex = -1;
|
|
7728
7828
|
li.dataset.path = f2.path;
|
|
7729
7829
|
li.classList.toggle("viewed", !onFileClick && STATE.viewedFiles.has(f2.path));
|
|
7730
|
-
li.style.setProperty("--lvl-pad", 12 + depth * 14
|
|
7830
|
+
li.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
|
|
7731
7831
|
const spacer = document.createElement("span");
|
|
7732
7832
|
spacer.className = "chev-spacer";
|
|
7733
7833
|
li.appendChild(spacer);
|
|
@@ -7808,7 +7908,7 @@
|
|
|
7808
7908
|
} else {
|
|
7809
7909
|
renderFlat(files, ul, onFileClick);
|
|
7810
7910
|
}
|
|
7811
|
-
$("#totals").textContent = files.length ? files.length
|
|
7911
|
+
$("#totals").textContent = files.length ? `${files.length} file${files.length === 1 ? "" : "s"}` : "";
|
|
7812
7912
|
$$(".sb-view-seg button").forEach((b2) => {
|
|
7813
7913
|
b2.classList.toggle("active", b2.dataset.view === STATE.sbView);
|
|
7814
7914
|
});
|
|
@@ -7846,7 +7946,7 @@
|
|
|
7846
7946
|
}
|
|
7847
7947
|
function createRefSelectorInput(options) {
|
|
7848
7948
|
const wrap = document.createElement("div");
|
|
7849
|
-
wrap.className =
|
|
7949
|
+
wrap.className = `ref-selector${options.extraClass ? ` ${options.extraClass}` : ""}`;
|
|
7850
7950
|
wrap.dataset.refSelector = "";
|
|
7851
7951
|
if (options.wrapperId)
|
|
7852
7952
|
wrap.id = options.wrapperId;
|
|
@@ -7897,7 +7997,7 @@
|
|
|
7897
7997
|
if (meta.branch) {
|
|
7898
7998
|
const b2 = document.createElement("span");
|
|
7899
7999
|
b2.className = "ref";
|
|
7900
|
-
b2.textContent =
|
|
8000
|
+
b2.textContent = `⎇ ${meta.branch}`;
|
|
7901
8001
|
el.appendChild(b2);
|
|
7902
8002
|
}
|
|
7903
8003
|
if (meta.totals) {
|
|
@@ -7909,13 +8009,13 @@
|
|
|
7909
8009
|
const u2 = document.createElement("span");
|
|
7910
8010
|
u2.className = "updated-at";
|
|
7911
8011
|
u2.title = "last updated";
|
|
7912
|
-
u2.textContent =
|
|
8012
|
+
u2.textContent = `updated ${new Date().toLocaleTimeString([], { hour12: false })}`;
|
|
7913
8013
|
el.appendChild(u2);
|
|
7914
8014
|
}
|
|
7915
8015
|
let SUPPRESS_SPY_UNTIL = 0;
|
|
7916
8016
|
function prefetchByPath(path) {
|
|
7917
8017
|
const card = document.querySelector(diffCardSelector(path));
|
|
7918
|
-
if (!card
|
|
8018
|
+
if (!card?.classList.contains("pending"))
|
|
7919
8019
|
return;
|
|
7920
8020
|
const f2 = STATE.files.find((x) => x.path === path);
|
|
7921
8021
|
if (!f2)
|
|
@@ -7990,7 +8090,7 @@
|
|
|
7990
8090
|
for (const dir of sidebarAncestorDirs(path)) {
|
|
7991
8091
|
if (STATE.collapsedDirs.delete(dir))
|
|
7992
8092
|
changed = true;
|
|
7993
|
-
const row = document.querySelector(
|
|
8093
|
+
const row = document.querySelector(`#filelist .tree-dir[data-dirpath="${CSS.escape(dir)}"]`);
|
|
7994
8094
|
row?.classList.remove("collapsed");
|
|
7995
8095
|
const icon = row?.querySelector(".dir-icon");
|
|
7996
8096
|
if (icon)
|
|
@@ -8051,7 +8151,7 @@
|
|
|
8051
8151
|
function updateTreeDirVisibility(dirMatches, filterActive = false) {
|
|
8052
8152
|
$$("#filelist .tree-dir").forEach((dir) => {
|
|
8053
8153
|
const childUl = dir.nextElementSibling;
|
|
8054
|
-
if (!childUl
|
|
8154
|
+
if (!childUl?.classList.contains("tree-children"))
|
|
8055
8155
|
return;
|
|
8056
8156
|
const anyVisible = !!childUl.querySelector(".tree-file:not(.hidden):not(.hidden-by-tests)");
|
|
8057
8157
|
const explicitVisible = dir.dataset.explicit === "true" && !filterActive;
|
|
@@ -8200,8 +8300,12 @@
|
|
|
8200
8300
|
});
|
|
8201
8301
|
}
|
|
8202
8302
|
function removeStandaloneSource() {
|
|
8203
|
-
document.querySelectorAll(".gdp-standalone-source").forEach((el) =>
|
|
8204
|
-
|
|
8303
|
+
document.querySelectorAll(".gdp-standalone-source").forEach((el) => {
|
|
8304
|
+
el.remove();
|
|
8305
|
+
});
|
|
8306
|
+
document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => {
|
|
8307
|
+
el.remove();
|
|
8308
|
+
});
|
|
8205
8309
|
}
|
|
8206
8310
|
function renderHelpPage() {
|
|
8207
8311
|
cancelActiveSourceLoad("navigation");
|
|
@@ -8348,7 +8452,7 @@
|
|
|
8348
8452
|
delete old.dataset.manualRendered;
|
|
8349
8453
|
delete old.dataset.manualLoad;
|
|
8350
8454
|
delete old.dataset.manualMode;
|
|
8351
|
-
old.style.minHeight =
|
|
8455
|
+
old.style.minHeight = `${f2.estimated_height_px || 80}px`;
|
|
8352
8456
|
old._diffData = null;
|
|
8353
8457
|
old._file = null;
|
|
8354
8458
|
} else {
|
|
@@ -8363,7 +8467,9 @@
|
|
|
8363
8467
|
ordered.push(createPlaceholder(f2));
|
|
8364
8468
|
}
|
|
8365
8469
|
});
|
|
8366
|
-
oldByKey.forEach((c2) =>
|
|
8470
|
+
oldByKey.forEach((c2) => {
|
|
8471
|
+
c2.remove();
|
|
8472
|
+
});
|
|
8367
8473
|
target.replaceChildren(...ordered);
|
|
8368
8474
|
for (let i2 = LOAD_QUEUE.length - 1;i2 >= 0; i2--) {
|
|
8369
8475
|
if (!LOAD_QUEUE[i2].card.isConnected)
|
|
@@ -8438,7 +8544,9 @@
|
|
|
8438
8544
|
return;
|
|
8439
8545
|
const form = new FormData;
|
|
8440
8546
|
form.set("dir", path);
|
|
8441
|
-
list2.forEach((file) =>
|
|
8547
|
+
list2.forEach((file) => {
|
|
8548
|
+
form.append("files", file, file.name);
|
|
8549
|
+
});
|
|
8442
8550
|
const res = await fetch("/_upload_files", {
|
|
8443
8551
|
method: "POST",
|
|
8444
8552
|
headers: { "X-Code-Viewer-Action": "1" },
|
|
@@ -8454,7 +8562,7 @@
|
|
|
8454
8562
|
dropPanel.className = "gdp-upload-panel";
|
|
8455
8563
|
const copy = document.createElement("div");
|
|
8456
8564
|
copy.className = "gdp-upload-copy";
|
|
8457
|
-
copy.textContent =
|
|
8565
|
+
copy.textContent = `Drop files into ${path || PROJECT_NAME || "repository"}`;
|
|
8458
8566
|
const input = document.createElement("input");
|
|
8459
8567
|
input.type = "file";
|
|
8460
8568
|
input.multiple = true;
|
|
@@ -8470,7 +8578,7 @@
|
|
|
8470
8578
|
};
|
|
8471
8579
|
input.addEventListener("change", async () => {
|
|
8472
8580
|
try {
|
|
8473
|
-
if (input.files
|
|
8581
|
+
if (input.files?.length)
|
|
8474
8582
|
await uploadFiles(path, input.files);
|
|
8475
8583
|
} catch {
|
|
8476
8584
|
fail();
|
|
@@ -8488,7 +8596,7 @@
|
|
|
8488
8596
|
dropPanel.classList.remove("dragging");
|
|
8489
8597
|
try {
|
|
8490
8598
|
const files = event.dataTransfer?.files;
|
|
8491
|
-
if (files
|
|
8599
|
+
if (files?.length)
|
|
8492
8600
|
await uploadFiles(path, files);
|
|
8493
8601
|
} catch {
|
|
8494
8602
|
fail();
|
|
@@ -8630,7 +8738,7 @@
|
|
|
8630
8738
|
meta.entries.forEach((entry) => {
|
|
8631
8739
|
const row = document.createElement("button");
|
|
8632
8740
|
row.type = "button";
|
|
8633
|
-
row.className =
|
|
8741
|
+
row.className = `gdp-repo-row ${entry.type}`;
|
|
8634
8742
|
const icon = document.createElement("span");
|
|
8635
8743
|
icon.className = entry.type === "tree" ? "dir-icon" : "d2h-icon-wrapper";
|
|
8636
8744
|
if (entry.type === "tree")
|
|
@@ -8670,7 +8778,7 @@
|
|
|
8670
8778
|
listWrapper.appendChild(list2);
|
|
8671
8779
|
listCard.appendChild(listWrapper);
|
|
8672
8780
|
shell.appendChild(listCard);
|
|
8673
|
-
if (meta.readme
|
|
8781
|
+
if (meta.readme?.text) {
|
|
8674
8782
|
const readme = document.createElement("section");
|
|
8675
8783
|
readme.className = "gdp-file-shell loaded gdp-repo-readme";
|
|
8676
8784
|
const wrapper = document.createElement("div");
|
|
@@ -8731,7 +8839,7 @@
|
|
|
8731
8839
|
params.set("recursive", "1");
|
|
8732
8840
|
appendScopeOmitDirsParam(params);
|
|
8733
8841
|
REPO_SIDEBAR_LOAD_REF = normalizedRef;
|
|
8734
|
-
const load2 = trackLoad(fetch(
|
|
8842
|
+
const load2 = trackLoad(fetch(`/_tree?${params.toString()}`).then((r2) => {
|
|
8735
8843
|
if (!r2.ok)
|
|
8736
8844
|
throw new Error("failed to load repository tree");
|
|
8737
8845
|
return r2.json();
|
|
@@ -8790,7 +8898,7 @@
|
|
|
8790
8898
|
card.dataset.status = f2.status || "M";
|
|
8791
8899
|
card.classList.toggle("viewed", STATE.viewedFiles.has(f2.path));
|
|
8792
8900
|
if (f2.estimated_height_px) {
|
|
8793
|
-
card.style.minHeight = f2.estimated_height_px
|
|
8901
|
+
card.style.minHeight = `${f2.estimated_height_px}px`;
|
|
8794
8902
|
}
|
|
8795
8903
|
const head = document.createElement("div");
|
|
8796
8904
|
head.className = "gdp-shell-header";
|
|
@@ -8817,7 +8925,9 @@
|
|
|
8817
8925
|
enqueueLoad(f2, card, 0);
|
|
8818
8926
|
});
|
|
8819
8927
|
}, { rootMargin: "1200px 0px 1600px 0px" });
|
|
8820
|
-
document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) =>
|
|
8928
|
+
document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) => {
|
|
8929
|
+
lazyObserver.observe(c2);
|
|
8930
|
+
});
|
|
8821
8931
|
}
|
|
8822
8932
|
window.addEventListener("scroll", () => enqueueInitialLoads(), {
|
|
8823
8933
|
passive: true
|
|
@@ -8888,12 +8998,14 @@
|
|
|
8888
8998
|
if (indicator)
|
|
8889
8999
|
indicator.hidden = true;
|
|
8890
9000
|
const body = card.querySelector(".gdp-shell-body");
|
|
9001
|
+
if (!body)
|
|
9002
|
+
return;
|
|
8891
9003
|
body.innerHTML = "";
|
|
8892
9004
|
const wrap = document.createElement("div");
|
|
8893
9005
|
wrap.className = "gdp-manual-load";
|
|
8894
9006
|
const note = document.createElement("div");
|
|
8895
9007
|
note.className = "gdp-manual-note";
|
|
8896
|
-
note.textContent = manualLoadReason(file)
|
|
9008
|
+
note.textContent = `${manualLoadReason(file)} - click to load diff`;
|
|
8897
9009
|
const previewBtn = document.createElement("button");
|
|
8898
9010
|
previewBtn.className = "gdp-show-full";
|
|
8899
9011
|
previewBtn.textContent = "Load preview";
|
|
@@ -8998,6 +9110,8 @@
|
|
|
8998
9110
|
card.classList.remove("loading");
|
|
8999
9111
|
card.classList.add("error");
|
|
9000
9112
|
const body = card.querySelector(".gdp-shell-body");
|
|
9113
|
+
if (!body)
|
|
9114
|
+
return;
|
|
9001
9115
|
body.innerHTML = '<div class="gdp-error">failed to load — <button class="retry">retry</button></div>';
|
|
9002
9116
|
const btn = body.querySelector(".retry");
|
|
9003
9117
|
if (btn)
|
|
@@ -9014,8 +9128,10 @@
|
|
|
9014
9128
|
if (head)
|
|
9015
9129
|
head.style.display = "none";
|
|
9016
9130
|
const body = card.querySelector(".gdp-shell-body");
|
|
9131
|
+
if (!body)
|
|
9132
|
+
return;
|
|
9017
9133
|
body.innerHTML = "";
|
|
9018
|
-
if (!data.diff
|
|
9134
|
+
if (!data.diff?.trim()) {
|
|
9019
9135
|
body.innerHTML = '<div class="gdp-info">No content</div>';
|
|
9020
9136
|
return;
|
|
9021
9137
|
}
|
|
@@ -9107,7 +9223,9 @@
|
|
|
9107
9223
|
const parsed = group.find((g) => g.hunk) || group[0];
|
|
9108
9224
|
if (!parsed.hunk)
|
|
9109
9225
|
return;
|
|
9110
|
-
group.forEach((g) =>
|
|
9226
|
+
group.forEach((g) => {
|
|
9227
|
+
g.tr.classList.add("gdp-hunk-row");
|
|
9228
|
+
});
|
|
9111
9229
|
infoRows.push({
|
|
9112
9230
|
tr: parsed.tr,
|
|
9113
9231
|
info: parsed.info,
|
|
@@ -9171,7 +9289,7 @@
|
|
|
9171
9289
|
setBusy(true);
|
|
9172
9290
|
const url = "/file_range?path=" + refPath + "&ref=" + encodeURIComponent(ref) + "&start=" + start + "&end=" + end;
|
|
9173
9291
|
trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
|
|
9174
|
-
if (!data
|
|
9292
|
+
if (!data?.lines) {
|
|
9175
9293
|
setBusy(false);
|
|
9176
9294
|
return;
|
|
9177
9295
|
}
|
|
@@ -9189,7 +9307,7 @@
|
|
|
9189
9307
|
item.bottomExpandedEnd = end;
|
|
9190
9308
|
for (const sib of item.siblings || [{ tr: item.tr }]) {
|
|
9191
9309
|
const ln = sib.tr.querySelector(".d2h-code-linenumber.d2h-info, .d2h-code-side-linenumber.d2h-info");
|
|
9192
|
-
const old = ln
|
|
9310
|
+
const old = ln?.querySelector(".gdp-expand-stack");
|
|
9193
9311
|
if (old)
|
|
9194
9312
|
old.remove();
|
|
9195
9313
|
}
|
|
@@ -9206,18 +9324,18 @@
|
|
|
9206
9324
|
if (isFirst) {
|
|
9207
9325
|
buttons.push({
|
|
9208
9326
|
direction: "up",
|
|
9209
|
-
title:
|
|
9327
|
+
title: `Show ${Math.min(STEP, remainingSize)} more lines`,
|
|
9210
9328
|
onClick: () => fetchAndInsert(Math.max(remainingStart, remainingEnd - STEP + 1), remainingEnd, "after")
|
|
9211
9329
|
});
|
|
9212
9330
|
} else {
|
|
9213
9331
|
buttons.push({
|
|
9214
9332
|
direction: "up",
|
|
9215
|
-
title:
|
|
9333
|
+
title: `Show ${Math.min(STEP, remainingSize)} more lines`,
|
|
9216
9334
|
onClick: () => fetchAndInsert(remainingStart, Math.min(remainingEnd, remainingStart + STEP - 1), "before")
|
|
9217
9335
|
});
|
|
9218
9336
|
buttons.push({
|
|
9219
9337
|
direction: "down",
|
|
9220
|
-
title:
|
|
9338
|
+
title: `Show ${Math.min(STEP, remainingSize)} more lines`,
|
|
9221
9339
|
onClick: () => fetchAndInsert(Math.max(remainingStart, remainingEnd - STEP + 1), remainingEnd, "after")
|
|
9222
9340
|
});
|
|
9223
9341
|
}
|
|
@@ -9261,12 +9379,14 @@
|
|
|
9261
9379
|
const syncHeight = () => {
|
|
9262
9380
|
const stack = stackRow.querySelector(".gdp-expand-stack");
|
|
9263
9381
|
const targetH = stack ? Math.max(20, stack.getBoundingClientRect().height) : 20;
|
|
9264
|
-
rows.forEach((row) =>
|
|
9382
|
+
rows.forEach((row) => {
|
|
9383
|
+
row.style.setProperty("height", `${targetH}px`, "important");
|
|
9384
|
+
});
|
|
9265
9385
|
};
|
|
9266
9386
|
requestAnimationFrame(syncHeight);
|
|
9267
9387
|
setTimeout(syncHeight, 100);
|
|
9268
9388
|
}
|
|
9269
|
-
function
|
|
9389
|
+
function _attachTrailingExpandControls(item, file, ref, refPath) {
|
|
9270
9390
|
const STEP = 20;
|
|
9271
9391
|
let nextNewStart = nextNewLine(item.hunk);
|
|
9272
9392
|
let nextOldStart = nextOldLine(item.hunk);
|
|
@@ -9292,29 +9412,37 @@
|
|
|
9292
9412
|
if (!rows.length)
|
|
9293
9413
|
return;
|
|
9294
9414
|
const setBusy = (busy) => {
|
|
9295
|
-
rows.forEach((row) =>
|
|
9296
|
-
btn.
|
|
9297
|
-
|
|
9415
|
+
rows.forEach((row) => {
|
|
9416
|
+
row.ln.querySelectorAll(".gdp-expand-btn").forEach((btn) => {
|
|
9417
|
+
btn.disabled = busy;
|
|
9418
|
+
});
|
|
9419
|
+
});
|
|
9298
9420
|
};
|
|
9299
9421
|
const fetchAndInsert = () => {
|
|
9300
9422
|
const range = window.GdpExpandLogic.trailingClickRange(nextNewStart, STEP);
|
|
9301
9423
|
setBusy(true);
|
|
9302
9424
|
const url = "/file_range?path=" + refPath + "&ref=" + encodeURIComponent(ref) + "&start=" + range.start + "&end=" + range.end;
|
|
9303
9425
|
trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
|
|
9304
|
-
const lines = data
|
|
9426
|
+
const lines = data?.lines || [];
|
|
9305
9427
|
if (!lines.length) {
|
|
9306
|
-
rows.forEach((row) =>
|
|
9428
|
+
rows.forEach((row) => {
|
|
9429
|
+
row.tr.remove();
|
|
9430
|
+
});
|
|
9307
9431
|
return;
|
|
9308
9432
|
}
|
|
9309
9433
|
const card = item.tr.closest(".d2h-file-wrapper");
|
|
9310
|
-
rows.forEach((row) =>
|
|
9434
|
+
rows.forEach((row) => {
|
|
9435
|
+
insertContextRows(row.tr, lines, range.start, nextOldStart, "before", row.sideIndex);
|
|
9436
|
+
});
|
|
9311
9437
|
const next = window.GdpExpandLogic.applyTrailingResult({ newStart: nextNewStart, oldStart: nextOldStart }, lines.length, STEP);
|
|
9312
9438
|
nextNewStart = next.newStart;
|
|
9313
9439
|
nextOldStart = next.oldStart;
|
|
9314
9440
|
if (card)
|
|
9315
9441
|
highlightInsertedSpans(card, file);
|
|
9316
9442
|
if (next.eof) {
|
|
9317
|
-
rows.forEach((row) =>
|
|
9443
|
+
rows.forEach((row) => {
|
|
9444
|
+
row.tr.remove();
|
|
9445
|
+
});
|
|
9318
9446
|
return;
|
|
9319
9447
|
}
|
|
9320
9448
|
setBusy(false);
|
|
@@ -9348,7 +9476,7 @@
|
|
|
9348
9476
|
let lnHtml;
|
|
9349
9477
|
if (isSplit) {
|
|
9350
9478
|
const num = sideIndex === 0 ? oldStart + i2 : newStart + i2;
|
|
9351
|
-
lnHtml =
|
|
9479
|
+
lnHtml = `<td class="d2h-code-side-linenumber d2h-cntx">${num}</td>`;
|
|
9352
9480
|
} else {
|
|
9353
9481
|
lnHtml = '<td class="d2h-code-linenumber d2h-cntx"><div class="line-num1">' + (oldStart + i2) + '</div><div class="line-num2">' + (newStart + i2) + "</div></td>";
|
|
9354
9482
|
}
|
|
@@ -9396,7 +9524,7 @@
|
|
|
9396
9524
|
title.textContent = "Loading file";
|
|
9397
9525
|
const message = document.createElement("div");
|
|
9398
9526
|
message.className = "gdp-source-loading-message";
|
|
9399
|
-
message.textContent = target.path
|
|
9527
|
+
message.textContent = `${target.path} at ${target.ref}`;
|
|
9400
9528
|
content.append(title, message);
|
|
9401
9529
|
if (onCancel) {
|
|
9402
9530
|
const button = document.createElement("button");
|
|
@@ -9420,7 +9548,7 @@
|
|
|
9420
9548
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
9421
9549
|
const view = document.createElement("div");
|
|
9422
9550
|
view.className = "gdp-source-viewer error";
|
|
9423
|
-
view.textContent = message ||
|
|
9551
|
+
view.textContent = message || `Cannot load ${target.path} at ${target.ref}`;
|
|
9424
9552
|
if (body)
|
|
9425
9553
|
body.replaceWith(view);
|
|
9426
9554
|
else
|
|
@@ -9437,7 +9565,7 @@
|
|
|
9437
9565
|
title.textContent = "Loading cancelled";
|
|
9438
9566
|
const message = document.createElement("div");
|
|
9439
9567
|
message.className = "gdp-source-loading-message";
|
|
9440
|
-
message.textContent = target.path
|
|
9568
|
+
message.textContent = `${target.path} at ${target.ref}`;
|
|
9441
9569
|
const retry = document.createElement("button");
|
|
9442
9570
|
retry.type = "button";
|
|
9443
9571
|
retry.className = "gdp-btn gdp-btn-sm";
|
|
@@ -9490,7 +9618,7 @@
|
|
|
9490
9618
|
const preview = document.createElement("div");
|
|
9491
9619
|
preview.className = "gdp-html-preview";
|
|
9492
9620
|
const frame = document.createElement("iframe");
|
|
9493
|
-
frame.title = target.path
|
|
9621
|
+
frame.title = `${target.path} preview`;
|
|
9494
9622
|
frame.srcdoc = html;
|
|
9495
9623
|
preview.appendChild(frame);
|
|
9496
9624
|
return preview;
|
|
@@ -9928,7 +10056,7 @@
|
|
|
9928
10056
|
const header = isStandalone ? null : document.createElement("div");
|
|
9929
10057
|
if (header) {
|
|
9930
10058
|
header.className = "gdp-source-meta";
|
|
9931
|
-
header.textContent = target.path
|
|
10059
|
+
header.textContent = `${target.path} @ ${target.ref}`;
|
|
9932
10060
|
}
|
|
9933
10061
|
const lang = inferLang(target.path);
|
|
9934
10062
|
const usesVirtualSource = shouldVirtualizeSource(textValue, lines) && !isVirtualSourceDisabled();
|
|
@@ -10271,7 +10399,7 @@
|
|
|
10271
10399
|
return;
|
|
10272
10400
|
matches = nextMatches;
|
|
10273
10401
|
active = matches.length ? Math.max(0, Math.min(active, matches.length - 1)) : -1;
|
|
10274
|
-
count.textContent = matches.length ? active + 1
|
|
10402
|
+
count.textContent = matches.length ? `${active + 1} / ${matches.length}` : "0 / 0";
|
|
10275
10403
|
if (active >= 0)
|
|
10276
10404
|
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * VIRTUAL_SOURCE_ROW_HEIGHT - VIRTUAL_SOURCE_ROW_HEIGHT * 3);
|
|
10277
10405
|
renderFn();
|
|
@@ -10293,7 +10421,7 @@
|
|
|
10293
10421
|
if (!matches.length)
|
|
10294
10422
|
return;
|
|
10295
10423
|
active = (active + direction + matches.length) % matches.length;
|
|
10296
|
-
count.textContent = active + 1
|
|
10424
|
+
count.textContent = `${active + 1} / ${matches.length}`;
|
|
10297
10425
|
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * VIRTUAL_SOURCE_ROW_HEIGHT - VIRTUAL_SOURCE_ROW_HEIGHT * 3);
|
|
10298
10426
|
renderFn();
|
|
10299
10427
|
};
|
|
@@ -10383,10 +10511,10 @@
|
|
|
10383
10511
|
scroller.className = "gdp-source-virtual-scroller";
|
|
10384
10512
|
scroller.tabIndex = 0;
|
|
10385
10513
|
scroller.setAttribute("role", "region");
|
|
10386
|
-
scroller.setAttribute("aria-label", target.path
|
|
10514
|
+
scroller.setAttribute("aria-label", `${target.path} source code`);
|
|
10387
10515
|
const spacer = document.createElement("div");
|
|
10388
10516
|
spacer.className = "gdp-source-virtual-spacer";
|
|
10389
|
-
spacer.style.height = Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT)
|
|
10517
|
+
spacer.style.height = `${Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
|
|
10390
10518
|
const windowEl = document.createElement("div");
|
|
10391
10519
|
windowEl.className = "gdp-source-virtual-window";
|
|
10392
10520
|
spacer.appendChild(windowEl);
|
|
@@ -10407,7 +10535,7 @@
|
|
|
10407
10535
|
renderedStart = start;
|
|
10408
10536
|
renderedEnd = end;
|
|
10409
10537
|
windowEl.replaceChildren();
|
|
10410
|
-
windowEl.style.transform =
|
|
10538
|
+
windowEl.style.transform = `translateY(${start * VIRTUAL_SOURCE_ROW_HEIGHT}px)`;
|
|
10411
10539
|
const fragment = document.createDocumentFragment();
|
|
10412
10540
|
for (let index = start;index < end; index++) {
|
|
10413
10541
|
const row = document.createElement("div");
|
|
@@ -10424,7 +10552,7 @@
|
|
|
10424
10552
|
const line = lines[index] ?? "";
|
|
10425
10553
|
const searchQuery = search?.query() || "";
|
|
10426
10554
|
const activeRange = search?.activeRange() || null;
|
|
10427
|
-
if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef
|
|
10555
|
+
if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef?.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
|
|
10428
10556
|
try {
|
|
10429
10557
|
code2.innerHTML = hljsRef.highlight(line, {
|
|
10430
10558
|
language: lang,
|
|
@@ -10499,7 +10627,7 @@
|
|
|
10499
10627
|
scroller.className = "gdp-source-virtual-scroller";
|
|
10500
10628
|
scroller.tabIndex = 0;
|
|
10501
10629
|
scroller.setAttribute("role", "region");
|
|
10502
|
-
scroller.setAttribute("aria-label", target.path
|
|
10630
|
+
scroller.setAttribute("aria-label", `${target.path} source code`);
|
|
10503
10631
|
const spacer = document.createElement("div");
|
|
10504
10632
|
spacer.className = "gdp-source-virtual-spacer";
|
|
10505
10633
|
const windowEl = document.createElement("div");
|
|
@@ -10513,15 +10641,17 @@
|
|
|
10513
10641
|
const targetLine = lineTargetStart(currentSourceLineTarget(target)) || 1;
|
|
10514
10642
|
let complete = initialComplete;
|
|
10515
10643
|
let totalRows = initialComplete ? Math.max(1, initialTotal) : Math.max(initialTotal || 1, initialStart + initialLines.length - 1, targetLine + VIRTUAL_SOURCE_PAGE_SIZE);
|
|
10516
|
-
initialLines.forEach((line, index) =>
|
|
10644
|
+
initialLines.forEach((line, index) => {
|
|
10645
|
+
lines.set(initialStart + index, line);
|
|
10646
|
+
});
|
|
10517
10647
|
requestedPages.add(Math.max(0, Math.floor((initialStart - 1) / VIRTUAL_SOURCE_PAGE_SIZE)));
|
|
10518
10648
|
for (let line = initialStart;line < initialStart + initialLines.length; line += VIRTUAL_SOURCE_PAGE_SIZE) {
|
|
10519
10649
|
requestedPages.add(Math.max(0, Math.floor((line - 1) / VIRTUAL_SOURCE_PAGE_SIZE)));
|
|
10520
10650
|
}
|
|
10521
10651
|
const updateTotals = () => {
|
|
10522
10652
|
SOURCE_CURSOR_TOTALS.set(sourceCursorKey(target), totalRows);
|
|
10523
|
-
summary.textContent = (complete ? totalRows.toLocaleString() : lines.size.toLocaleString()
|
|
10524
|
-
spacer.style.height = Math.max(1, totalRows * VIRTUAL_SOURCE_ROW_HEIGHT)
|
|
10653
|
+
summary.textContent = (complete ? totalRows.toLocaleString() : `${lines.size.toLocaleString()}+`) + " lines loaded from " + formatBytes(size) + ". More rows load as you scroll.";
|
|
10654
|
+
spacer.style.height = `${Math.max(1, totalRows * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
|
|
10525
10655
|
};
|
|
10526
10656
|
const loadPage = (line) => {
|
|
10527
10657
|
if (signal?.aborted || complete && line > totalRows)
|
|
@@ -10537,7 +10667,9 @@
|
|
|
10537
10667
|
trackLoad(fetch(buildFileRangeUrl(target, start, end), { signal }).then((res) => res.ok ? res.json() : null).then((data) => {
|
|
10538
10668
|
if (!data || signal?.aborted)
|
|
10539
10669
|
return;
|
|
10540
|
-
data.lines.forEach((lineValue, index) =>
|
|
10670
|
+
data.lines.forEach((lineValue, index) => {
|
|
10671
|
+
lines.set(data.start + index, lineValue);
|
|
10672
|
+
});
|
|
10541
10673
|
totalRows = data.complete ? Math.max(1, data.total) : Math.max(totalRows, data.total, end + VIRTUAL_SOURCE_PAGE_SIZE);
|
|
10542
10674
|
complete = data.complete === true;
|
|
10543
10675
|
updateTotals();
|
|
@@ -10569,7 +10701,7 @@
|
|
|
10569
10701
|
renderedStart = start;
|
|
10570
10702
|
renderedEnd = end;
|
|
10571
10703
|
windowEl.replaceChildren();
|
|
10572
|
-
windowEl.style.transform =
|
|
10704
|
+
windowEl.style.transform = `translateY(${start * VIRTUAL_SOURCE_ROW_HEIGHT}px)`;
|
|
10573
10705
|
const fragment = document.createDocumentFragment();
|
|
10574
10706
|
for (let index = start;index < end; index++) {
|
|
10575
10707
|
const lineNumber = index + 1;
|
|
@@ -10589,7 +10721,7 @@
|
|
|
10589
10721
|
const line = lines.get(lineNumber);
|
|
10590
10722
|
if (line == null) {
|
|
10591
10723
|
code2.textContent = "";
|
|
10592
|
-
} else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef
|
|
10724
|
+
} else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef?.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
|
|
10593
10725
|
try {
|
|
10594
10726
|
code2.innerHTML = hljsRef.highlight(line, {
|
|
10595
10727
|
language: lang,
|
|
@@ -10689,7 +10821,7 @@
|
|
|
10689
10821
|
const header = isStandalone ? null : document.createElement("div");
|
|
10690
10822
|
if (header) {
|
|
10691
10823
|
header.className = "gdp-source-meta";
|
|
10692
|
-
header.textContent = target.path
|
|
10824
|
+
header.textContent = `${target.path} @ ${target.ref}`;
|
|
10693
10825
|
view.appendChild(header);
|
|
10694
10826
|
}
|
|
10695
10827
|
const lineTarget = lineTargetStart(currentSourceLineTarget(target)) || 1;
|
|
@@ -10730,7 +10862,7 @@
|
|
|
10730
10862
|
if (!isStandalone) {
|
|
10731
10863
|
const meta = document.createElement("div");
|
|
10732
10864
|
meta.className = "gdp-source-meta";
|
|
10733
|
-
meta.textContent = target.path
|
|
10865
|
+
meta.textContent = `${target.path} @ ${target.ref}`;
|
|
10734
10866
|
view.appendChild(meta);
|
|
10735
10867
|
}
|
|
10736
10868
|
const url = buildRawFileUrl(target);
|
|
@@ -10760,7 +10892,7 @@
|
|
|
10760
10892
|
img.alt = "";
|
|
10761
10893
|
img.addEventListener("load", () => {
|
|
10762
10894
|
const resolution = document.createElement("span");
|
|
10763
|
-
resolution.textContent = img.naturalWidth
|
|
10895
|
+
resolution.textContent = `${img.naturalWidth} x ${img.naturalHeight}`;
|
|
10764
10896
|
info.appendChild(resolution);
|
|
10765
10897
|
}, { once: true });
|
|
10766
10898
|
view.appendChild(img);
|
|
@@ -10770,7 +10902,7 @@
|
|
|
10770
10902
|
else
|
|
10771
10903
|
card.appendChild(view);
|
|
10772
10904
|
}
|
|
10773
|
-
function
|
|
10905
|
+
function _renderSourceBinary(card, target) {
|
|
10774
10906
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
10775
10907
|
const isStandalone = card.classList.contains("gdp-standalone-source");
|
|
10776
10908
|
const view = document.createElement("div");
|
|
@@ -10783,7 +10915,7 @@
|
|
|
10783
10915
|
if (!isStandalone) {
|
|
10784
10916
|
const meta = document.createElement("div");
|
|
10785
10917
|
meta.className = "gdp-source-meta";
|
|
10786
|
-
meta.textContent = target.path
|
|
10918
|
+
meta.textContent = `${target.path} @ ${target.ref}`;
|
|
10787
10919
|
view.appendChild(meta);
|
|
10788
10920
|
}
|
|
10789
10921
|
view.appendChild(link2);
|
|
@@ -10835,7 +10967,9 @@
|
|
|
10835
10967
|
const repoTarget = repoFileTargetFromRoute();
|
|
10836
10968
|
setPageMode();
|
|
10837
10969
|
removeStandaloneSource();
|
|
10838
|
-
document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) =>
|
|
10970
|
+
document.querySelectorAll(".gdp-repo-blob-layout").forEach((el) => {
|
|
10971
|
+
el.remove();
|
|
10972
|
+
});
|
|
10839
10973
|
const card = document.createElement("article");
|
|
10840
10974
|
card.className = "gdp-file-shell loaded gdp-standalone-source gdp-source-mode";
|
|
10841
10975
|
card.dataset.path = target.path;
|
|
@@ -10941,7 +11075,7 @@
|
|
|
10941
11075
|
return;
|
|
10942
11076
|
if (!response.ok) {
|
|
10943
11077
|
finishSourceLoad(req);
|
|
10944
|
-
renderSourceError(card, target,
|
|
11078
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
10945
11079
|
return;
|
|
10946
11080
|
}
|
|
10947
11081
|
const textValue = await response.text();
|
|
@@ -10963,7 +11097,7 @@
|
|
|
10963
11097
|
renderSourceCancelled(card, target);
|
|
10964
11098
|
return;
|
|
10965
11099
|
}
|
|
10966
|
-
renderSourceError(card, target,
|
|
11100
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
10967
11101
|
}
|
|
10968
11102
|
}
|
|
10969
11103
|
function scrollStandaloneSourceLine(card, line) {
|
|
@@ -10976,7 +11110,7 @@
|
|
|
10976
11110
|
virtualScroller.__gdpRenderVirtualSource?.();
|
|
10977
11111
|
return;
|
|
10978
11112
|
}
|
|
10979
|
-
const row = card.querySelector(
|
|
11113
|
+
const row = card.querySelector(`.gdp-source-table tr[data-line="${String(line)}"]`);
|
|
10980
11114
|
if (row)
|
|
10981
11115
|
row.scrollIntoView({ block: "center" });
|
|
10982
11116
|
}
|
|
@@ -11117,7 +11251,8 @@
|
|
|
11117
11251
|
}
|
|
11118
11252
|
const total = (file.additions || 0) + (file.deletions || 0);
|
|
11119
11253
|
const SEG = 5;
|
|
11120
|
-
let aSeg
|
|
11254
|
+
let aSeg;
|
|
11255
|
+
let dSeg;
|
|
11121
11256
|
if (total === 0) {
|
|
11122
11257
|
aSeg = 0;
|
|
11123
11258
|
dSeg = 0;
|
|
@@ -11174,7 +11309,7 @@
|
|
|
11174
11309
|
card.style.minHeight = "";
|
|
11175
11310
|
mountDiff(card, file, data);
|
|
11176
11311
|
applyDiffRouteFocus(card);
|
|
11177
|
-
card.style.containIntrinsicSize = Math.max(card.offsetHeight, file.estimated_height_px || 200)
|
|
11312
|
+
card.style.containIntrinsicSize = `${Math.max(card.offsetHeight, file.estimated_height_px || 200)}px`;
|
|
11178
11313
|
applyViewedToCard(card, STATE.viewedFiles.has(file.path), true);
|
|
11179
11314
|
if (data.truncated && data.mode === "preview") {
|
|
11180
11315
|
addExpandHunksUI(file, data, card);
|
|
@@ -11201,15 +11336,15 @@
|
|
|
11201
11336
|
const step = Math.min(10, remaining);
|
|
11202
11337
|
const moreBtn = document.createElement("button");
|
|
11203
11338
|
moreBtn.className = "gdp-show-full";
|
|
11204
|
-
moreBtn.textContent =
|
|
11339
|
+
moreBtn.textContent = `Show next ${step} hunk${step === 1 ? "" : "s"}`;
|
|
11205
11340
|
moreBtn.addEventListener("click", () => loadMore(rendered + step, false));
|
|
11206
11341
|
const allBtn = document.createElement("button");
|
|
11207
11342
|
allBtn.className = "gdp-show-full secondary";
|
|
11208
|
-
allBtn.textContent =
|
|
11343
|
+
allBtn.textContent = `Show all (${remaining} remaining)`;
|
|
11209
11344
|
allBtn.addEventListener("click", () => loadMore(total, true));
|
|
11210
11345
|
const note = document.createElement("span");
|
|
11211
11346
|
note.className = "gdp-hunk-note";
|
|
11212
|
-
note.textContent = rendered
|
|
11347
|
+
note.textContent = `${rendered} / ${total} hunks shown`;
|
|
11213
11348
|
wrap.appendChild(note);
|
|
11214
11349
|
wrap.appendChild(moreBtn);
|
|
11215
11350
|
wrap.appendChild(allBtn);
|
|
@@ -11257,10 +11392,10 @@
|
|
|
11257
11392
|
if (!STATE.syntaxHighlight)
|
|
11258
11393
|
return;
|
|
11259
11394
|
const hljsRef = getHljs();
|
|
11260
|
-
if (!hljsRef
|
|
11395
|
+
if (!hljsRef?.highlight)
|
|
11261
11396
|
return;
|
|
11262
11397
|
const lang = inferLang(file.path);
|
|
11263
|
-
if (!lang || !hljsRef.getLanguage
|
|
11398
|
+
if (!lang || !hljsRef.getLanguage?.(lang))
|
|
11264
11399
|
return;
|
|
11265
11400
|
const spans = card.querySelectorAll("tr.gdp-inserted-ctx .d2h-code-line-ctn:not([data-gdp-hl])");
|
|
11266
11401
|
spans.forEach((s2) => {
|
|
@@ -11288,10 +11423,10 @@
|
|
|
11288
11423
|
if (!("requestIdleCallback" in window))
|
|
11289
11424
|
return;
|
|
11290
11425
|
const hljsRef = getHljs();
|
|
11291
|
-
if (!hljsRef
|
|
11426
|
+
if (!hljsRef?.highlight)
|
|
11292
11427
|
return;
|
|
11293
11428
|
const lang = inferLang(file.path);
|
|
11294
|
-
if (!lang || !hljsRef.getLanguage
|
|
11429
|
+
if (!lang || !hljsRef.getLanguage?.(lang))
|
|
11295
11430
|
return;
|
|
11296
11431
|
const work = (deadline) => {
|
|
11297
11432
|
const spans = card.querySelectorAll(".d2h-code-line-ctn:not([data-gdp-hl])");
|
|
@@ -11353,17 +11488,17 @@
|
|
|
11353
11488
|
return AUDIO_RE.test(p2);
|
|
11354
11489
|
}
|
|
11355
11490
|
function fileURL(path, ref) {
|
|
11356
|
-
return
|
|
11491
|
+
return `/_file?path=${encodeURIComponent(path)}&ref=${ref}`;
|
|
11357
11492
|
}
|
|
11358
11493
|
function mediaTag(path, ref) {
|
|
11359
11494
|
const url = fileURL(path, ref);
|
|
11360
11495
|
if (isVideo(path)) {
|
|
11361
|
-
return
|
|
11496
|
+
return `<video src="${url}" controls preload="metadata"></video>`;
|
|
11362
11497
|
}
|
|
11363
11498
|
if (isAudio(path)) {
|
|
11364
|
-
return
|
|
11499
|
+
return `<audio src="${url}" controls preload="metadata"></audio>`;
|
|
11365
11500
|
}
|
|
11366
|
-
return
|
|
11501
|
+
return `<img src="${url}" alt="" loading="lazy">`;
|
|
11367
11502
|
}
|
|
11368
11503
|
function enhanceMediaCard(file, card) {
|
|
11369
11504
|
const path = file.path;
|
|
@@ -11377,7 +11512,8 @@
|
|
|
11377
11512
|
return;
|
|
11378
11513
|
const container = document.createElement("div");
|
|
11379
11514
|
container.className = "gdp-media";
|
|
11380
|
-
let leftHTML
|
|
11515
|
+
let leftHTML;
|
|
11516
|
+
let rightHTML;
|
|
11381
11517
|
if (file.status === "A") {
|
|
11382
11518
|
leftHTML = '<div class="media-empty">Not in HEAD</div>';
|
|
11383
11519
|
rightHTML = mediaTag(path, "worktree");
|
|
@@ -11401,7 +11537,7 @@
|
|
|
11401
11537
|
handler._raf = null;
|
|
11402
11538
|
if (performance.now() < SUPPRESS_SPY_UNTIL)
|
|
11403
11539
|
return;
|
|
11404
|
-
const topbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--topbar-h")) || 56;
|
|
11540
|
+
const topbarH = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--topbar-h"), 10) || 56;
|
|
11405
11541
|
const scanY = topbarH + 24;
|
|
11406
11542
|
const cards = document.querySelectorAll(".gdp-file-shell");
|
|
11407
11543
|
for (const w of cards) {
|
|
@@ -11419,7 +11555,7 @@
|
|
|
11419
11555
|
markActive(best);
|
|
11420
11556
|
const recentlyTouched = performance.now() - (window.__gdpSidebarTouchedAt || 0) < 1500;
|
|
11421
11557
|
if (!recentlyTouched) {
|
|
11422
|
-
const li = document.querySelector(
|
|
11558
|
+
const li = document.querySelector(`#filelist li[data-path="${CSS.escape(best)}"]`);
|
|
11423
11559
|
if (li) {
|
|
11424
11560
|
const sb = document.querySelector("#sidebar");
|
|
11425
11561
|
if (!sb)
|
|
@@ -11443,7 +11579,7 @@
|
|
|
11443
11579
|
window.addEventListener("scroll", handler, { passive: true });
|
|
11444
11580
|
handler(new Event("scroll"));
|
|
11445
11581
|
}
|
|
11446
|
-
function
|
|
11582
|
+
function _collapseAll(force) {
|
|
11447
11583
|
STATE.collapsed = typeof force === "boolean" ? force : !STATE.collapsed;
|
|
11448
11584
|
document.querySelectorAll(".gdp-file-shell.loaded .d2h-file-wrapper").forEach((w) => {
|
|
11449
11585
|
const body = w.querySelector(".d2h-files-diff, .d2h-file-diff");
|
|
@@ -11487,7 +11623,7 @@
|
|
|
11487
11623
|
});
|
|
11488
11624
|
function applySidebarWidth(w) {
|
|
11489
11625
|
const cw = Math.max(180, Math.min(900, w));
|
|
11490
|
-
document.documentElement.style.setProperty("--sidebar-w", cw
|
|
11626
|
+
document.documentElement.style.setProperty("--sidebar-w", `${cw}px`);
|
|
11491
11627
|
STATE.sbWidth = cw;
|
|
11492
11628
|
localStorage.setItem("gdp:sbwidth", String(cw));
|
|
11493
11629
|
}
|
|
@@ -11528,14 +11664,14 @@
|
|
|
11528
11664
|
currentW = startW;
|
|
11529
11665
|
document.body.classList.add("gdp-resizing");
|
|
11530
11666
|
preview.style.display = "block";
|
|
11531
|
-
preview.style.left = startW
|
|
11667
|
+
preview.style.left = `${startW}px`;
|
|
11532
11668
|
e2.preventDefault();
|
|
11533
11669
|
});
|
|
11534
11670
|
window.addEventListener("mousemove", (e2) => {
|
|
11535
11671
|
if (!dragging)
|
|
11536
11672
|
return;
|
|
11537
11673
|
currentW = clamp(startW + (e2.clientX - startX));
|
|
11538
|
-
preview.style.left = currentW
|
|
11674
|
+
preview.style.left = `${currentW}px`;
|
|
11539
11675
|
});
|
|
11540
11676
|
window.addEventListener("mouseup", () => {
|
|
11541
11677
|
if (!dragging)
|
|
@@ -11869,7 +12005,7 @@
|
|
|
11869
12005
|
state.items.forEach((item, index) => {
|
|
11870
12006
|
const row = document.createElement("button");
|
|
11871
12007
|
row.type = "button";
|
|
11872
|
-
row.id =
|
|
12008
|
+
row.id = `gdp-palette-item-${index}`;
|
|
11873
12009
|
row.className = "gdp-palette-row";
|
|
11874
12010
|
row.setAttribute("role", "option");
|
|
11875
12011
|
row.setAttribute("aria-selected", index === state.selected ? "true" : "false");
|
|
@@ -11881,10 +12017,10 @@
|
|
|
11881
12017
|
title.textContent = item.path.split("/").pop() || item.path;
|
|
11882
12018
|
appendHighlightedPath(detail, item.displayPath, item.ranges);
|
|
11883
12019
|
if (item.old_path && item.displayPath !== item.old_path) {
|
|
11884
|
-
detail.appendChild(document.createTextNode(
|
|
12020
|
+
detail.appendChild(document.createTextNode(` ${item.old_path}`));
|
|
11885
12021
|
}
|
|
11886
12022
|
} else {
|
|
11887
|
-
title.textContent = item.path
|
|
12023
|
+
title.textContent = `${item.path}:${item.line}`;
|
|
11888
12024
|
detail.textContent = item.preview;
|
|
11889
12025
|
}
|
|
11890
12026
|
row.append(title, detail);
|
|
@@ -11902,7 +12038,7 @@
|
|
|
11902
12038
|
syncPaletteSelection(state);
|
|
11903
12039
|
}
|
|
11904
12040
|
function syncPaletteSelection(state) {
|
|
11905
|
-
state.input.setAttribute("aria-activedescendant", state.selected >= 0 ?
|
|
12041
|
+
state.input.setAttribute("aria-activedescendant", state.selected >= 0 ? `gdp-palette-item-${state.selected}` : "");
|
|
11906
12042
|
state.list.querySelectorAll(".gdp-palette-row").forEach((row, index) => {
|
|
11907
12043
|
row.setAttribute("aria-selected", index === state.selected ? "true" : "false");
|
|
11908
12044
|
if (index === state.selected)
|
|
@@ -11917,7 +12053,7 @@
|
|
|
11917
12053
|
const params = new URLSearchParams;
|
|
11918
12054
|
params.set("ref", ref);
|
|
11919
12055
|
appendScopeOmitDirsParam(params);
|
|
11920
|
-
const res = await trackLoad(fetch(
|
|
12056
|
+
const res = await trackLoad(fetch(`/_files?${params.toString()}`).then((r2) => {
|
|
11921
12057
|
if (!r2.ok)
|
|
11922
12058
|
throw new Error("failed to load files");
|
|
11923
12059
|
return r2.json();
|
|
@@ -11965,7 +12101,7 @@
|
|
|
11965
12101
|
}) : [];
|
|
11966
12102
|
state.items = limitPaletteResults(base2);
|
|
11967
12103
|
state.selected = state.items.length ? 0 : -1;
|
|
11968
|
-
state.status.textContent = source === "diff" ? state.diffSnapshot.length
|
|
12104
|
+
state.status.textContent = source === "diff" ? `${state.diffSnapshot.length} diff files` : "Type to search repository files";
|
|
11969
12105
|
renderPalette(state);
|
|
11970
12106
|
return;
|
|
11971
12107
|
}
|
|
@@ -11987,7 +12123,7 @@
|
|
|
11987
12123
|
}));
|
|
11988
12124
|
}
|
|
11989
12125
|
state.selected = state.items.length ? 0 : -1;
|
|
11990
|
-
state.status.textContent = state.items.length ? state.items.length
|
|
12126
|
+
state.status.textContent = state.items.length ? `${state.items.length} results` : "No results";
|
|
11991
12127
|
renderPalette(state);
|
|
11992
12128
|
}
|
|
11993
12129
|
function updateGrepPalette(state, query) {
|
|
@@ -12027,7 +12163,7 @@
|
|
|
12027
12163
|
}
|
|
12028
12164
|
const controller = new AbortController;
|
|
12029
12165
|
state.controller = controller;
|
|
12030
|
-
trackLoad(fetch(
|
|
12166
|
+
trackLoad(fetch(`/_grep?${params.toString()}`, {
|
|
12031
12167
|
signal: controller.signal
|
|
12032
12168
|
}).then((r2) => {
|
|
12033
12169
|
if (!r2.ok)
|
|
@@ -12285,7 +12421,7 @@
|
|
|
12285
12421
|
if (!isPlainPageKey && !isCtrlArrowKey)
|
|
12286
12422
|
return false;
|
|
12287
12423
|
const scroller = findMainScrollTarget();
|
|
12288
|
-
if (!scroller
|
|
12424
|
+
if (!scroller?.matches("#content .gdp-source-virtual-scroller"))
|
|
12289
12425
|
return false;
|
|
12290
12426
|
const pageDown = key === "pagedown" || key === "arrowdown";
|
|
12291
12427
|
const pageUp = key === "pageup" || key === "arrowup";
|
|
@@ -12343,7 +12479,7 @@
|
|
|
12343
12479
|
if (STATE.route.path)
|
|
12344
12480
|
params.set("path", STATE.route.path);
|
|
12345
12481
|
appendScopeOmitDirsParam(params);
|
|
12346
|
-
return trackLoad(fetch(
|
|
12482
|
+
return trackLoad(fetch(`/_tree?${params.toString()}`).then((r2) => {
|
|
12347
12483
|
if (!r2.ok)
|
|
12348
12484
|
throw new Error("failed to load repository tree");
|
|
12349
12485
|
return r2.json();
|
|
@@ -12372,7 +12508,7 @@
|
|
|
12372
12508
|
params.set("to", STATE.to);
|
|
12373
12509
|
if (options.force)
|
|
12374
12510
|
params.set("nocache", "1");
|
|
12375
|
-
const url =
|
|
12511
|
+
const url = `/diff.json${params.toString() ? `?${params.toString()}` : ""}`;
|
|
12376
12512
|
return trackLoad(fetch(url).then((r2) => r2.json())).then((data) => {
|
|
12377
12513
|
renderShell(data);
|
|
12378
12514
|
setStatus("live");
|
|
@@ -12430,6 +12566,8 @@
|
|
|
12430
12566
|
const popover = $("#ref-popover");
|
|
12431
12567
|
const popBody = popover.querySelector(".rp-body");
|
|
12432
12568
|
const popSearch = popover.querySelector(".rp-search");
|
|
12569
|
+
if (!popBody || !popSearch)
|
|
12570
|
+
return;
|
|
12433
12571
|
let popTarget = null;
|
|
12434
12572
|
function fetchRefs() {
|
|
12435
12573
|
return fetch("/_refs").then((r2) => r2.json()).then((refs) => {
|
|
@@ -12438,37 +12576,75 @@
|
|
|
12438
12576
|
}
|
|
12439
12577
|
fetchRefs();
|
|
12440
12578
|
let popTab = "commits";
|
|
12579
|
+
let commitSearchTimer = null;
|
|
12580
|
+
let commitSearchSeq = 0;
|
|
12581
|
+
let commitSearchAbort = null;
|
|
12582
|
+
let commitSearchLoading = false;
|
|
12583
|
+
function fetchCommitRefs(query) {
|
|
12584
|
+
const seq = ++commitSearchSeq;
|
|
12585
|
+
if (commitSearchAbort)
|
|
12586
|
+
commitSearchAbort.abort();
|
|
12587
|
+
commitSearchAbort = new AbortController;
|
|
12588
|
+
const url = `/_commits?max=100&q=${encodeURIComponent((query || "").trim())}`;
|
|
12589
|
+
return fetch(url, { signal: commitSearchAbort.signal }).then((r2) => r2.json()).then((refs) => {
|
|
12590
|
+
if (seq !== commitSearchSeq)
|
|
12591
|
+
return;
|
|
12592
|
+
commitSearchLoading = false;
|
|
12593
|
+
REFS.commits = refs.commits || [];
|
|
12594
|
+
if (!popover.hidden && popTab === "commits") {
|
|
12595
|
+
buildPopBody(popSearch.value);
|
|
12596
|
+
}
|
|
12597
|
+
}).catch(() => {
|
|
12598
|
+
if (seq === commitSearchSeq)
|
|
12599
|
+
commitSearchLoading = false;
|
|
12600
|
+
});
|
|
12601
|
+
}
|
|
12602
|
+
function scheduleCommitSearch(query) {
|
|
12603
|
+
if (commitSearchTimer)
|
|
12604
|
+
clearTimeout(commitSearchTimer);
|
|
12605
|
+
commitSearchLoading = true;
|
|
12606
|
+
commitSearchTimer = setTimeout(() => {
|
|
12607
|
+
commitSearchTimer = null;
|
|
12608
|
+
fetchCommitRefs(query);
|
|
12609
|
+
}, 150);
|
|
12610
|
+
}
|
|
12441
12611
|
function buildPopBody(query) {
|
|
12442
12612
|
const q = (query || "").toLowerCase().trim();
|
|
12443
12613
|
const m = (s2) => !q || String(s2).toLowerCase().includes(q);
|
|
12444
12614
|
const html = [];
|
|
12445
12615
|
if (popTab === "commits") {
|
|
12446
|
-
|
|
12616
|
+
if (commitSearchLoading) {
|
|
12617
|
+
html.push('<div class="rp-empty">loading commits...</div>');
|
|
12618
|
+
popBody.innerHTML = html.join("");
|
|
12619
|
+
highlightCurrentInPopover();
|
|
12620
|
+
return;
|
|
12621
|
+
}
|
|
12622
|
+
const commits = (REFS.commits || []).filter((commit) => m(`${commit.sha} ${commit.subject} ${commit.author}`));
|
|
12447
12623
|
if (!commits.length) {
|
|
12448
12624
|
html.push('<div class="rp-empty">no commits</div>');
|
|
12449
12625
|
}
|
|
12450
|
-
for (const
|
|
12451
|
-
|
|
12452
|
-
if (!sha)
|
|
12626
|
+
for (const commit of commits) {
|
|
12627
|
+
if (!commit.sha)
|
|
12453
12628
|
continue;
|
|
12454
|
-
|
|
12629
|
+
const shortSha = commit.sha.slice(0, 7);
|
|
12630
|
+
html.push('<div class="rp-item-commit" data-val="' + escapeAttr(commit.sha) + '"><div class="row1"><span class="sha">' + escapeHtml2(shortSha) + '</span><span class="subject" title="' + escapeAttr(commit.subject || "") + '">' + escapeHtml2(commit.subject || "") + '</span></div><div class="row2"><span class="author">' + escapeHtml2(commit.author || "") + '</span><span class="when">' + escapeHtml2(commit.when || "") + "</span></div></div>");
|
|
12455
12631
|
}
|
|
12456
12632
|
} else if (popTab === "branches") {
|
|
12457
|
-
const branches = (REFS.branches || []).filter(m);
|
|
12633
|
+
const branches = (REFS.branches || []).filter((b2) => m(b2.name));
|
|
12458
12634
|
if (!branches.length) {
|
|
12459
12635
|
html.push('<div class="rp-empty">no branches</div>');
|
|
12460
12636
|
}
|
|
12461
|
-
for (const
|
|
12462
|
-
const cur =
|
|
12463
|
-
html.push('<div class="rp-item-ref" data-val="' + escapeAttr(
|
|
12637
|
+
for (const branch of branches) {
|
|
12638
|
+
const cur = branch.name === REFS.current;
|
|
12639
|
+
html.push('<div class="rp-item-ref" data-val="' + escapeAttr(branch.name) + '"><div class="row1"><span class="name">' + escapeHtml2(branch.name) + "</span>" + (cur ? '<span class="badge cur">current</span>' : '<span class="badge">branch</span>') + "</div>" + (branch.when ? '<div class="row2"><span class="when">' + escapeHtml2(branch.when) + "</span></div>" : "") + "</div>");
|
|
12464
12640
|
}
|
|
12465
12641
|
} else if (popTab === "tags") {
|
|
12466
|
-
const tags = (REFS.tags || []).filter(m);
|
|
12642
|
+
const tags = (REFS.tags || []).filter((t2) => m(t2.name));
|
|
12467
12643
|
if (!tags.length) {
|
|
12468
12644
|
html.push('<div class="rp-empty">no tags</div>');
|
|
12469
12645
|
}
|
|
12470
|
-
for (const
|
|
12471
|
-
html.push('<div class="rp-item-ref" data-val="' + escapeAttr(
|
|
12646
|
+
for (const tag of tags) {
|
|
12647
|
+
html.push('<div class="rp-item-ref" data-val="' + escapeAttr(tag.name) + '"><div class="row1"><span class="name">' + escapeHtml2(tag.name) + '</span><span class="badge">tag</span></div>' + (tag.when ? '<div class="row2"><span class="when">' + escapeHtml2(tag.when) + "</span></div>" : "") + "</div>");
|
|
12472
12648
|
}
|
|
12473
12649
|
}
|
|
12474
12650
|
popBody.innerHTML = html.join("");
|
|
@@ -12502,6 +12678,8 @@
|
|
|
12502
12678
|
function openPopover(input) {
|
|
12503
12679
|
popTarget = input;
|
|
12504
12680
|
popSearch.value = "";
|
|
12681
|
+
if (popTab === "commits")
|
|
12682
|
+
scheduleCommitSearch("");
|
|
12505
12683
|
buildPopBody("");
|
|
12506
12684
|
const cur = (input.value || "").trim();
|
|
12507
12685
|
popover.querySelectorAll(".rp-chip").forEach((c2) => {
|
|
@@ -12510,8 +12688,8 @@
|
|
|
12510
12688
|
popover.hidden = false;
|
|
12511
12689
|
const r2 = input.getBoundingClientRect();
|
|
12512
12690
|
const popWidth = Math.min(560, Math.floor(window.innerWidth * 0.9));
|
|
12513
|
-
popover.style.left = Math.max(8, Math.min(r2.left, window.innerWidth - popWidth - 8))
|
|
12514
|
-
popover.style.top = r2.bottom + 4
|
|
12691
|
+
popover.style.left = `${Math.max(8, Math.min(r2.left, window.innerWidth - popWidth - 8))}px`;
|
|
12692
|
+
popover.style.top = `${r2.bottom + 4}px`;
|
|
12515
12693
|
setTimeout(() => popSearch.focus(), 0);
|
|
12516
12694
|
}
|
|
12517
12695
|
function closePopover() {
|
|
@@ -12539,13 +12717,17 @@
|
|
|
12539
12717
|
});
|
|
12540
12718
|
renderStandaloneSource({ path: STATE.route.path, ref });
|
|
12541
12719
|
});
|
|
12542
|
-
popSearch.addEventListener("input", () =>
|
|
12720
|
+
popSearch.addEventListener("input", () => {
|
|
12721
|
+
if (popTab === "commits")
|
|
12722
|
+
scheduleCommitSearch(popSearch.value);
|
|
12723
|
+
buildPopBody(popSearch.value);
|
|
12724
|
+
});
|
|
12543
12725
|
popSearch.addEventListener("keydown", (e2) => {
|
|
12544
12726
|
if (e2.key === "Escape") {
|
|
12545
12727
|
closePopover();
|
|
12546
12728
|
}
|
|
12547
12729
|
if (e2.key === "Enter") {
|
|
12548
|
-
const first = popBody.querySelector(".rp-item");
|
|
12730
|
+
const first = popBody.querySelector(".rp-item-commit, .rp-item-ref");
|
|
12549
12731
|
if (first)
|
|
12550
12732
|
first.click();
|
|
12551
12733
|
}
|
|
@@ -12567,7 +12749,11 @@
|
|
|
12567
12749
|
popover.querySelectorAll(".rp-tab").forEach((t2) => {
|
|
12568
12750
|
t2.addEventListener("click", () => {
|
|
12569
12751
|
popTab = t2.dataset.tab || "commits";
|
|
12570
|
-
popover.querySelectorAll(".rp-tab").forEach((b2) =>
|
|
12752
|
+
popover.querySelectorAll(".rp-tab").forEach((b2) => {
|
|
12753
|
+
b2.classList.toggle("active", b2 === t2);
|
|
12754
|
+
});
|
|
12755
|
+
if (popTab === "commits")
|
|
12756
|
+
scheduleCommitSearch(popSearch.value);
|
|
12571
12757
|
buildPopBody(popSearch.value);
|
|
12572
12758
|
});
|
|
12573
12759
|
});
|