@youtyan/code-viewer 0.1.16 → 0.1.18
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 +34 -8
- package/dist/code-viewer.js +2374 -0
- package/package.json +24 -18
- package/web/app.js +489 -211
- package/web/style.css +12 -0
- package/web-src/routes.ts +0 -148
- package/web-src/server/cache.ts +0 -64
- package/web-src/server/dev-assets.ts +0 -37
- package/web-src/server/dev.ts +0 -100
- package/web-src/server/git.ts +0 -506
- package/web-src/server/preview.ts +0 -1160
- package/web-src/server/range.ts +0 -236
- package/web-src/server/runtime.d.ts +0 -61
- package/web-src/server/search.ts +0 -104
- package/web-src/types.ts +0 -142
package/web/app.js
CHANGED
|
@@ -21,6 +21,21 @@
|
|
|
21
21
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
// web-src/catch-up.ts
|
|
25
|
+
function shouldCatchUpDiff(route) {
|
|
26
|
+
return route.screen !== "repo" && !(route.screen === "file" && route.view === "blob");
|
|
27
|
+
}
|
|
28
|
+
function createCatchUpGate(now, minIntervalMs) {
|
|
29
|
+
let lastForceAt = 0;
|
|
30
|
+
return function shouldRun() {
|
|
31
|
+
const current = now();
|
|
32
|
+
if (current - lastForceAt < minIntervalMs)
|
|
33
|
+
return false;
|
|
34
|
+
lastForceAt = current;
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
// web-src/expand-logic.ts
|
|
25
40
|
function initExpandState(prevHunkEndNew, hunkNewStart) {
|
|
26
41
|
return {
|
|
@@ -78,20 +93,6 @@
|
|
|
78
93
|
applyTrailingResult
|
|
79
94
|
};
|
|
80
95
|
|
|
81
|
-
// web-src/file-navigation.ts
|
|
82
|
-
function nextVisibleFileIndex(currentIndex, itemCount, direction) {
|
|
83
|
-
if (itemCount <= 0)
|
|
84
|
-
return -1;
|
|
85
|
-
if (currentIndex < 0)
|
|
86
|
-
return direction > 0 ? 0 : itemCount - 1;
|
|
87
|
-
return Math.max(0, Math.min(itemCount - 1, currentIndex + direction));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// web-src/file-path-copy.ts
|
|
91
|
-
function filePathClipboardText(path) {
|
|
92
|
-
return path || "";
|
|
93
|
-
}
|
|
94
|
-
|
|
95
96
|
// web-src/file-filter.ts
|
|
96
97
|
function normalizeFileFilterQuery(value) {
|
|
97
98
|
return (value || "").toLowerCase().trim();
|
|
@@ -131,6 +132,20 @@
|
|
|
131
132
|
};
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
// web-src/file-navigation.ts
|
|
136
|
+
function nextVisibleFileIndex(currentIndex, itemCount, direction) {
|
|
137
|
+
if (itemCount <= 0)
|
|
138
|
+
return -1;
|
|
139
|
+
if (currentIndex < 0)
|
|
140
|
+
return direction > 0 ? 0 : itemCount - 1;
|
|
141
|
+
return Math.max(0, Math.min(itemCount - 1, currentIndex + direction));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// web-src/file-path-copy.ts
|
|
145
|
+
function filePathClipboardText(path) {
|
|
146
|
+
return path || "";
|
|
147
|
+
}
|
|
148
|
+
|
|
134
149
|
// web-src/focus-scope.ts
|
|
135
150
|
function isEditableKeyTarget(target) {
|
|
136
151
|
if (!target)
|
|
@@ -433,147 +448,6 @@
|
|
|
433
448
|
return null;
|
|
434
449
|
}
|
|
435
450
|
|
|
436
|
-
// web-src/search-palette.ts
|
|
437
|
-
var PALETTE_RESULT_LIMIT = 50;
|
|
438
|
-
function limitPaletteResults(items) {
|
|
439
|
-
return items.slice(0, PALETTE_RESULT_LIMIT);
|
|
440
|
-
}
|
|
441
|
-
function movePaletteSelection(index, count, direction) {
|
|
442
|
-
if (count <= 0)
|
|
443
|
-
return -1;
|
|
444
|
-
if (index < 0)
|
|
445
|
-
return direction > 0 ? 0 : count - 1;
|
|
446
|
-
return (index + direction + count) % count;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// web-src/catch-up.ts
|
|
450
|
-
function shouldCatchUpDiff(route) {
|
|
451
|
-
return route.screen !== "repo" && !(route.screen === "file" && route.view === "blob");
|
|
452
|
-
}
|
|
453
|
-
function createCatchUpGate(now, minIntervalMs) {
|
|
454
|
-
let lastForceAt = 0;
|
|
455
|
-
return function shouldRun() {
|
|
456
|
-
const current = now();
|
|
457
|
-
if (current - lastForceAt < minIntervalMs)
|
|
458
|
-
return false;
|
|
459
|
-
lastForceAt = current;
|
|
460
|
-
return true;
|
|
461
|
-
};
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// web-src/routes.ts
|
|
465
|
-
function assertNever(value) {
|
|
466
|
-
throw new Error("unhandled route: " + JSON.stringify(value));
|
|
467
|
-
}
|
|
468
|
-
function parseLegacyRange(value, fallback) {
|
|
469
|
-
const raw = value || "";
|
|
470
|
-
const sep = raw.indexOf("..");
|
|
471
|
-
if (sep < 0)
|
|
472
|
-
return fallback;
|
|
473
|
-
return {
|
|
474
|
-
from: raw.slice(0, sep) || fallback.from,
|
|
475
|
-
to: raw.slice(sep + 2) || fallback.to
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
function parseLineTarget(value) {
|
|
479
|
-
const raw = value || "";
|
|
480
|
-
const range = /^(\d+)-(\d+)$/.exec(raw);
|
|
481
|
-
if (range) {
|
|
482
|
-
const a = Number(range[1]);
|
|
483
|
-
const b = Number(range[2]);
|
|
484
|
-
const start = Math.min(a, b);
|
|
485
|
-
const end = Math.max(a, b);
|
|
486
|
-
if (start > 0)
|
|
487
|
-
return { start, end };
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
const line = Number(raw);
|
|
491
|
-
return Number.isInteger(line) && line > 0 ? line : undefined;
|
|
492
|
-
}
|
|
493
|
-
function formatLineTarget(line) {
|
|
494
|
-
return typeof line === "number" ? String(line) : line.start + "-" + line.end;
|
|
495
|
-
}
|
|
496
|
-
function parseRoute(pathname, search, fallbackRange) {
|
|
497
|
-
const params = new URLSearchParams(search);
|
|
498
|
-
const legacyRange = parseLegacyRange(params.get("range"), fallbackRange);
|
|
499
|
-
const range = {
|
|
500
|
-
from: params.get("from") || legacyRange.from,
|
|
501
|
-
to: params.get("to") || legacyRange.to
|
|
502
|
-
};
|
|
503
|
-
switch (pathname) {
|
|
504
|
-
case "/":
|
|
505
|
-
case "/index.html":
|
|
506
|
-
return {
|
|
507
|
-
screen: "repo",
|
|
508
|
-
ref: params.get("ref") || params.get("target") || "worktree",
|
|
509
|
-
path: params.get("path") || "",
|
|
510
|
-
range
|
|
511
|
-
};
|
|
512
|
-
case "/todif":
|
|
513
|
-
case "/todiff":
|
|
514
|
-
return {
|
|
515
|
-
screen: "diff",
|
|
516
|
-
range,
|
|
517
|
-
...params.get("path") ? { path: params.get("path") || "" } : {},
|
|
518
|
-
...parseLineTarget(params.get("line")) ? { line: parseLineTarget(params.get("line")) } : {}
|
|
519
|
-
};
|
|
520
|
-
case "/file": {
|
|
521
|
-
const path = params.get("path") || "";
|
|
522
|
-
const target = params.get("target") || "";
|
|
523
|
-
const ref = target || params.get("ref") || "worktree";
|
|
524
|
-
const line = parseLineTarget(params.get("line"));
|
|
525
|
-
if (!path)
|
|
526
|
-
return { screen: "unknown", reason: "missing-path", rawPathname: pathname, rawSearch: search, range };
|
|
527
|
-
return { screen: "file", path, ref, range, view: target ? "blob" : "detail", ...line ? { line } : {} };
|
|
528
|
-
}
|
|
529
|
-
case "/help":
|
|
530
|
-
return {
|
|
531
|
-
screen: "help",
|
|
532
|
-
range,
|
|
533
|
-
lang: params.get("lang") || "en",
|
|
534
|
-
section: params.get("section") || "keybindings"
|
|
535
|
-
};
|
|
536
|
-
default:
|
|
537
|
-
return { screen: "unknown", reason: "unknown-pathname", rawPathname: pathname, rawSearch: search, range };
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
function buildRoute(route) {
|
|
541
|
-
switch (route.screen) {
|
|
542
|
-
case "repo": {
|
|
543
|
-
const params = new URLSearchParams;
|
|
544
|
-
if (route.ref && route.ref !== "worktree")
|
|
545
|
-
params.set("ref", route.ref);
|
|
546
|
-
if (route.path)
|
|
547
|
-
params.set("path", route.path);
|
|
548
|
-
const qs = params.toString();
|
|
549
|
-
return "/" + (qs ? "?" + qs : "");
|
|
550
|
-
}
|
|
551
|
-
case "file":
|
|
552
|
-
if (route.view === "blob") {
|
|
553
|
-
return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
|
|
554
|
-
}
|
|
555
|
-
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)) : "");
|
|
556
|
-
case "diff":
|
|
557
|
-
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)) : "");
|
|
558
|
-
case "help": {
|
|
559
|
-
const params = new URLSearchParams;
|
|
560
|
-
if (route.lang && route.lang !== "en")
|
|
561
|
-
params.set("lang", route.lang);
|
|
562
|
-
if (route.section && route.section !== "keybindings")
|
|
563
|
-
params.set("section", route.section);
|
|
564
|
-
const qs = params.toString();
|
|
565
|
-
return "/help" + (qs ? "?" + qs : "");
|
|
566
|
-
}
|
|
567
|
-
case "unknown":
|
|
568
|
-
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
|
|
569
|
-
default:
|
|
570
|
-
return assertNever(route);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
function buildRawFileUrl(target) {
|
|
574
|
-
return "/_file?path=" + encodeURIComponent(target.path) + "&ref=" + encodeURIComponent(target.ref || "worktree");
|
|
575
|
-
}
|
|
576
|
-
|
|
577
451
|
// node_modules/markdown-it/lib/common/utils.mjs
|
|
578
452
|
var exports_utils = {};
|
|
579
453
|
__export(exports_utils, {
|
|
@@ -6155,6 +6029,119 @@
|
|
|
6155
6029
|
md.core.ruler.after("inline", "footnote_tail", footnote_tail);
|
|
6156
6030
|
}
|
|
6157
6031
|
|
|
6032
|
+
// web-src/routes.ts
|
|
6033
|
+
function assertNever(value) {
|
|
6034
|
+
throw new Error("unhandled route: " + JSON.stringify(value));
|
|
6035
|
+
}
|
|
6036
|
+
function parseLegacyRange(value, fallback) {
|
|
6037
|
+
const raw = value || "";
|
|
6038
|
+
const sep = raw.indexOf("..");
|
|
6039
|
+
if (sep < 0)
|
|
6040
|
+
return fallback;
|
|
6041
|
+
return {
|
|
6042
|
+
from: raw.slice(0, sep) || fallback.from,
|
|
6043
|
+
to: raw.slice(sep + 2) || fallback.to
|
|
6044
|
+
};
|
|
6045
|
+
}
|
|
6046
|
+
function parseLineTarget(value) {
|
|
6047
|
+
const raw = value || "";
|
|
6048
|
+
const range = /^(\d+)-(\d+)$/.exec(raw);
|
|
6049
|
+
if (range) {
|
|
6050
|
+
const a2 = Number(range[1]);
|
|
6051
|
+
const b2 = Number(range[2]);
|
|
6052
|
+
const start = Math.min(a2, b2);
|
|
6053
|
+
const end = Math.max(a2, b2);
|
|
6054
|
+
if (start > 0)
|
|
6055
|
+
return { start, end };
|
|
6056
|
+
return;
|
|
6057
|
+
}
|
|
6058
|
+
const line = Number(raw);
|
|
6059
|
+
return Number.isInteger(line) && line > 0 ? line : undefined;
|
|
6060
|
+
}
|
|
6061
|
+
function formatLineTarget(line) {
|
|
6062
|
+
return typeof line === "number" ? String(line) : line.start + "-" + line.end;
|
|
6063
|
+
}
|
|
6064
|
+
function parseRoute(pathname, search, fallbackRange) {
|
|
6065
|
+
const params = new URLSearchParams(search);
|
|
6066
|
+
const legacyRange = parseLegacyRange(params.get("range"), fallbackRange);
|
|
6067
|
+
const range = {
|
|
6068
|
+
from: params.get("from") || legacyRange.from,
|
|
6069
|
+
to: params.get("to") || legacyRange.to
|
|
6070
|
+
};
|
|
6071
|
+
switch (pathname) {
|
|
6072
|
+
case "/":
|
|
6073
|
+
case "/index.html":
|
|
6074
|
+
return {
|
|
6075
|
+
screen: "repo",
|
|
6076
|
+
ref: params.get("ref") || params.get("target") || "worktree",
|
|
6077
|
+
path: params.get("path") || "",
|
|
6078
|
+
range
|
|
6079
|
+
};
|
|
6080
|
+
case "/todif":
|
|
6081
|
+
case "/todiff":
|
|
6082
|
+
return {
|
|
6083
|
+
screen: "diff",
|
|
6084
|
+
range,
|
|
6085
|
+
...params.get("path") ? { path: params.get("path") || "" } : {},
|
|
6086
|
+
...parseLineTarget(params.get("line")) ? { line: parseLineTarget(params.get("line")) } : {}
|
|
6087
|
+
};
|
|
6088
|
+
case "/file": {
|
|
6089
|
+
const path = params.get("path") || "";
|
|
6090
|
+
const target = params.get("target") || "";
|
|
6091
|
+
const ref = target || params.get("ref") || "worktree";
|
|
6092
|
+
const line = parseLineTarget(params.get("line"));
|
|
6093
|
+
if (!path)
|
|
6094
|
+
return { screen: "unknown", reason: "missing-path", rawPathname: pathname, rawSearch: search, range };
|
|
6095
|
+
return { screen: "file", path, ref, range, view: target ? "blob" : "detail", ...line ? { line } : {} };
|
|
6096
|
+
}
|
|
6097
|
+
case "/help":
|
|
6098
|
+
return {
|
|
6099
|
+
screen: "help",
|
|
6100
|
+
range,
|
|
6101
|
+
lang: params.get("lang") || "en",
|
|
6102
|
+
section: params.get("section") || "keybindings"
|
|
6103
|
+
};
|
|
6104
|
+
default:
|
|
6105
|
+
return { screen: "unknown", reason: "unknown-pathname", rawPathname: pathname, rawSearch: search, range };
|
|
6106
|
+
}
|
|
6107
|
+
}
|
|
6108
|
+
function buildRoute(route) {
|
|
6109
|
+
switch (route.screen) {
|
|
6110
|
+
case "repo": {
|
|
6111
|
+
const params = new URLSearchParams;
|
|
6112
|
+
if (route.ref && route.ref !== "worktree")
|
|
6113
|
+
params.set("ref", route.ref);
|
|
6114
|
+
if (route.path)
|
|
6115
|
+
params.set("path", route.path);
|
|
6116
|
+
const qs = params.toString();
|
|
6117
|
+
return "/" + (qs ? "?" + qs : "");
|
|
6118
|
+
}
|
|
6119
|
+
case "file":
|
|
6120
|
+
if (route.view === "blob") {
|
|
6121
|
+
return "/file?path=" + encodeURIComponent(route.path) + "&target=" + encodeURIComponent(route.ref || "worktree") + (route.line ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
|
|
6122
|
+
}
|
|
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 ? "&line=" + encodeURIComponent(formatLineTarget(route.line)) : "");
|
|
6124
|
+
case "diff":
|
|
6125
|
+
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
|
+
case "help": {
|
|
6127
|
+
const params = new URLSearchParams;
|
|
6128
|
+
if (route.lang && route.lang !== "en")
|
|
6129
|
+
params.set("lang", route.lang);
|
|
6130
|
+
if (route.section && route.section !== "keybindings")
|
|
6131
|
+
params.set("section", route.section);
|
|
6132
|
+
const qs = params.toString();
|
|
6133
|
+
return "/help" + (qs ? "?" + qs : "");
|
|
6134
|
+
}
|
|
6135
|
+
case "unknown":
|
|
6136
|
+
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree");
|
|
6137
|
+
default:
|
|
6138
|
+
return assertNever(route);
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
function buildRawFileUrl(target) {
|
|
6142
|
+
return "/_file?path=" + encodeURIComponent(target.path) + "&ref=" + encodeURIComponent(target.ref || "worktree");
|
|
6143
|
+
}
|
|
6144
|
+
|
|
6158
6145
|
// web-src/markdown-preview.ts
|
|
6159
6146
|
var mermaidPromise = null;
|
|
6160
6147
|
var mermaidInitialized = false;
|
|
@@ -6728,6 +6715,19 @@
|
|
|
6728
6715
|
return { width: rect.width || 800, height: rect.height || 600 };
|
|
6729
6716
|
}
|
|
6730
6717
|
|
|
6718
|
+
// web-src/search-palette.ts
|
|
6719
|
+
var PALETTE_RESULT_LIMIT = 50;
|
|
6720
|
+
function limitPaletteResults(items) {
|
|
6721
|
+
return items.slice(0, PALETTE_RESULT_LIMIT);
|
|
6722
|
+
}
|
|
6723
|
+
function movePaletteSelection(index, count, direction) {
|
|
6724
|
+
if (count <= 0)
|
|
6725
|
+
return -1;
|
|
6726
|
+
if (index < 0)
|
|
6727
|
+
return direction > 0 ? 0 : count - 1;
|
|
6728
|
+
return (index + direction + count) % count;
|
|
6729
|
+
}
|
|
6730
|
+
|
|
6731
6731
|
// web-src/ws-highlight.ts
|
|
6732
6732
|
function isWhitespaceOnlyInlineHighlight(text2) {
|
|
6733
6733
|
return !!text2 && !/\S/.test(text2);
|
|
@@ -6844,10 +6844,41 @@
|
|
|
6844
6844
|
title: "Keyboard Shortcuts",
|
|
6845
6845
|
intro: "Use these shortcuts to move between panels and navigate files without leaving the keyboard.",
|
|
6846
6846
|
groups: [
|
|
6847
|
-
{
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6847
|
+
{
|
|
6848
|
+
title: "Global",
|
|
6849
|
+
rows: [
|
|
6850
|
+
["Ctrl+K", "Open file palette"],
|
|
6851
|
+
["Ctrl+G", "Open grep palette"],
|
|
6852
|
+
["/", "Focus file filter"],
|
|
6853
|
+
["t", "Toggle theme"]
|
|
6854
|
+
]
|
|
6855
|
+
},
|
|
6856
|
+
{
|
|
6857
|
+
title: "Panels",
|
|
6858
|
+
rows: [
|
|
6859
|
+
["Ctrl+H", "Focus sidebar"],
|
|
6860
|
+
["Ctrl+L", "Focus main panel"]
|
|
6861
|
+
]
|
|
6862
|
+
},
|
|
6863
|
+
{
|
|
6864
|
+
title: "Sidebar",
|
|
6865
|
+
rows: [
|
|
6866
|
+
["j / k", "Move selection down / up"],
|
|
6867
|
+
["Ctrl+D / Ctrl+U", "Move selection by half a page"],
|
|
6868
|
+
["gg / Shift+G", "Move to top / bottom"],
|
|
6869
|
+
["Enter", "Open selected item"],
|
|
6870
|
+
["h / l", "Collapse / expand directory"]
|
|
6871
|
+
]
|
|
6872
|
+
},
|
|
6873
|
+
{
|
|
6874
|
+
title: "Main Panel",
|
|
6875
|
+
rows: [
|
|
6876
|
+
["j / k", "Move code cursor down / up"],
|
|
6877
|
+
["Ctrl+D / Ctrl+U", "Move code cursor by half a page"],
|
|
6878
|
+
["gg / Shift+G", "Move code cursor to top / bottom"],
|
|
6879
|
+
["gp / gc", "Switch to Preview / Code tab"]
|
|
6880
|
+
]
|
|
6881
|
+
}
|
|
6851
6882
|
]
|
|
6852
6883
|
}
|
|
6853
6884
|
}
|
|
@@ -6861,10 +6892,41 @@
|
|
|
6861
6892
|
title: "キーバインド",
|
|
6862
6893
|
intro: "キーボードだけでパネル移動、ファイル選択、スクロールを行うためのショートカットです。",
|
|
6863
6894
|
groups: [
|
|
6864
|
-
{
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6895
|
+
{
|
|
6896
|
+
title: "グローバル",
|
|
6897
|
+
rows: [
|
|
6898
|
+
["Ctrl+K", "ファイルパレットを開く"],
|
|
6899
|
+
["Ctrl+G", "grep パレットを開く"],
|
|
6900
|
+
["/", "ファイルフィルターへフォーカス"],
|
|
6901
|
+
["t", "テーマ切り替え"]
|
|
6902
|
+
]
|
|
6903
|
+
},
|
|
6904
|
+
{
|
|
6905
|
+
title: "パネル",
|
|
6906
|
+
rows: [
|
|
6907
|
+
["Ctrl+H", "サイドバーへフォーカス"],
|
|
6908
|
+
["Ctrl+L", "メインパネルへフォーカス"]
|
|
6909
|
+
]
|
|
6910
|
+
},
|
|
6911
|
+
{
|
|
6912
|
+
title: "サイドバー",
|
|
6913
|
+
rows: [
|
|
6914
|
+
["j / k", "選択を下 / 上へ移動"],
|
|
6915
|
+
["Ctrl+D / Ctrl+U", "半ページ分選択を移動"],
|
|
6916
|
+
["gg / Shift+G", "先頭 / 末尾へ移動"],
|
|
6917
|
+
["Enter", "選択項目を開く"],
|
|
6918
|
+
["h / l", "ディレクトリを閉じる / 開く"]
|
|
6919
|
+
]
|
|
6920
|
+
},
|
|
6921
|
+
{
|
|
6922
|
+
title: "メインパネル",
|
|
6923
|
+
rows: [
|
|
6924
|
+
["j / k", "コードカーソルを下 / 上へ移動"],
|
|
6925
|
+
["Ctrl+D / Ctrl+U", "コードカーソルを半ページ分移動"],
|
|
6926
|
+
["gg / Shift+G", "コードカーソルを先頭 / 末尾へ移動"],
|
|
6927
|
+
["gp / gc", "Preview / Code タブへ切り替え"]
|
|
6928
|
+
]
|
|
6929
|
+
}
|
|
6868
6930
|
]
|
|
6869
6931
|
}
|
|
6870
6932
|
}
|
|
@@ -6915,7 +6977,10 @@
|
|
|
6915
6977
|
}
|
|
6916
6978
|
function resetSourceCursorForTarget(target, totalLines) {
|
|
6917
6979
|
const routeLine = lineTargetStart(currentSourceLineTarget(target));
|
|
6918
|
-
SOURCE_CURSOR = {
|
|
6980
|
+
SOURCE_CURSOR = {
|
|
6981
|
+
target,
|
|
6982
|
+
line: Math.max(1, Math.min(totalLines, routeLine || 1))
|
|
6983
|
+
};
|
|
6919
6984
|
}
|
|
6920
6985
|
function scrollSourceCursorIntoView(cursor, edge = "nearest") {
|
|
6921
6986
|
const scroller = findMainScrollTarget();
|
|
@@ -7004,7 +7069,10 @@
|
|
|
7004
7069
|
return;
|
|
7005
7070
|
const target = findMainScrollTarget();
|
|
7006
7071
|
if (target) {
|
|
7007
|
-
target.scrollTo({
|
|
7072
|
+
target.scrollTo({
|
|
7073
|
+
top: edge === "top" ? 0 : target.scrollHeight,
|
|
7074
|
+
behavior: "auto"
|
|
7075
|
+
});
|
|
7008
7076
|
return;
|
|
7009
7077
|
}
|
|
7010
7078
|
const top = edge === "top" ? 0 : Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
|
@@ -7033,7 +7101,9 @@
|
|
|
7033
7101
|
}
|
|
7034
7102
|
function normalizeScopeOmitDirs(value) {
|
|
7035
7103
|
const raw = Array.isArray(value) ? value : value.split(/[\n,]+/);
|
|
7036
|
-
return [
|
|
7104
|
+
return [
|
|
7105
|
+
...new Set(raw.map((item) => item.trim()).filter((item) => item && item.length <= 64 && !item.includes("/") && !item.includes("\\") && item !== "." && item !== ".." && item !== ".git"))
|
|
7106
|
+
].slice(0, 100).sort((a2, b2) => a2.localeCompare(b2));
|
|
7037
7107
|
}
|
|
7038
7108
|
function scopeOmitDirsStorageKey() {
|
|
7039
7109
|
return SCOPE_OMIT_DIRS_STORAGE_KEY_PREFIX + (PROJECT_NAME || "default");
|
|
@@ -7494,7 +7564,14 @@
|
|
|
7494
7564
|
refreshRepositoryTreeAfterSettings();
|
|
7495
7565
|
}
|
|
7496
7566
|
function buildTree(files) {
|
|
7497
|
-
const root = {
|
|
7567
|
+
const root = {
|
|
7568
|
+
name: "",
|
|
7569
|
+
dirs: {},
|
|
7570
|
+
files: [],
|
|
7571
|
+
path: "",
|
|
7572
|
+
minOrder: Infinity,
|
|
7573
|
+
explicit: true
|
|
7574
|
+
};
|
|
7498
7575
|
for (const f2 of files) {
|
|
7499
7576
|
const parts = f2.path.split("/");
|
|
7500
7577
|
let node = root;
|
|
@@ -7504,7 +7581,13 @@
|
|
|
7504
7581
|
const p2 = parts[i2];
|
|
7505
7582
|
acc = acc ? acc + "/" + p2 : p2;
|
|
7506
7583
|
if (!node.dirs[p2]) {
|
|
7507
|
-
node.dirs[p2] = {
|
|
7584
|
+
node.dirs[p2] = {
|
|
7585
|
+
name: p2,
|
|
7586
|
+
dirs: {},
|
|
7587
|
+
files: [],
|
|
7588
|
+
path: acc,
|
|
7589
|
+
minOrder: Infinity
|
|
7590
|
+
};
|
|
7508
7591
|
}
|
|
7509
7592
|
node = node.dirs[p2];
|
|
7510
7593
|
if (typeof f2.order === "number" && f2.order < node.minOrder)
|
|
@@ -7544,7 +7627,11 @@
|
|
|
7544
7627
|
items.push({ kind: "dir", sortKey: d2.minOrder, dir: d2 });
|
|
7545
7628
|
}
|
|
7546
7629
|
for (const f2 of node.files) {
|
|
7547
|
-
items.push({
|
|
7630
|
+
items.push({
|
|
7631
|
+
kind: "file",
|
|
7632
|
+
sortKey: f2.order != null ? f2.order : Infinity,
|
|
7633
|
+
file: f2
|
|
7634
|
+
});
|
|
7548
7635
|
}
|
|
7549
7636
|
items.sort((a2, b2) => a2.sortKey - b2.sortKey);
|
|
7550
7637
|
for (const item of items) {
|
|
@@ -7665,7 +7752,9 @@
|
|
|
7665
7752
|
scheduleMainSurfaceFocus();
|
|
7666
7753
|
});
|
|
7667
7754
|
if (!onFileClick)
|
|
7668
|
-
li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
|
|
7755
|
+
li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
|
|
7756
|
+
passive: true
|
|
7757
|
+
});
|
|
7669
7758
|
ul.appendChild(li);
|
|
7670
7759
|
}
|
|
7671
7760
|
}
|
|
@@ -7698,7 +7787,9 @@
|
|
|
7698
7787
|
scheduleMainSurfaceFocus();
|
|
7699
7788
|
});
|
|
7700
7789
|
if (!onFileClick)
|
|
7701
|
-
li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
|
|
7790
|
+
li.addEventListener("mouseenter", () => prefetchByPath(f2.path), {
|
|
7791
|
+
passive: true
|
|
7792
|
+
});
|
|
7702
7793
|
ul.appendChild(li);
|
|
7703
7794
|
});
|
|
7704
7795
|
}
|
|
@@ -7998,7 +8089,13 @@
|
|
|
7998
8089
|
});
|
|
7999
8090
|
}
|
|
8000
8091
|
function escapeHtml2(s2) {
|
|
8001
|
-
return String(s2 == null ? "" : s2).replace(/[&<>"']/g, (c2) => ({
|
|
8092
|
+
return String(s2 == null ? "" : s2).replace(/[&<>"']/g, (c2) => ({
|
|
8093
|
+
"&": "&",
|
|
8094
|
+
"<": "<",
|
|
8095
|
+
">": ">",
|
|
8096
|
+
'"': """,
|
|
8097
|
+
"'": "'"
|
|
8098
|
+
})[c2]);
|
|
8002
8099
|
}
|
|
8003
8100
|
function sourceTargetsEqual(a2, b2) {
|
|
8004
8101
|
return !!a2 && !!b2 && a2.path === b2.path && a2.ref === b2.ref;
|
|
@@ -8030,7 +8127,10 @@
|
|
|
8030
8127
|
return { path: file.path, ref };
|
|
8031
8128
|
}
|
|
8032
8129
|
function currentRange() {
|
|
8033
|
-
return {
|
|
8130
|
+
return {
|
|
8131
|
+
from: STATE.from || DEFAULT_RANGE.from,
|
|
8132
|
+
to: STATE.to || DEFAULT_RANGE.to
|
|
8133
|
+
};
|
|
8034
8134
|
}
|
|
8035
8135
|
function sourceTargetFromRoute() {
|
|
8036
8136
|
return STATE.route.screen === "file" ? { path: STATE.route.path, ref: STATE.route.ref } : null;
|
|
@@ -8053,7 +8153,12 @@
|
|
|
8053
8153
|
STATE.repoRef = nextRoute.ref || "worktree";
|
|
8054
8154
|
}
|
|
8055
8155
|
const url = buildRoute(nextRoute);
|
|
8056
|
-
const state = nextRoute.screen === "file" ? {
|
|
8156
|
+
const state = nextRoute.screen === "file" ? {
|
|
8157
|
+
screen: "file",
|
|
8158
|
+
path: nextRoute.path,
|
|
8159
|
+
ref: nextRoute.ref,
|
|
8160
|
+
view: nextRoute.view || "detail"
|
|
8161
|
+
} : { view: nextRoute.screen };
|
|
8057
8162
|
if (replace2)
|
|
8058
8163
|
history.replaceState(state, "", url);
|
|
8059
8164
|
else
|
|
@@ -8074,13 +8179,23 @@
|
|
|
8074
8179
|
link2.classList.toggle("active", active);
|
|
8075
8180
|
link2.setAttribute("aria-current", active ? "page" : "false");
|
|
8076
8181
|
if (link2.dataset.route === "repo") {
|
|
8077
|
-
link2.href = buildRoute({
|
|
8182
|
+
link2.href = buildRoute({
|
|
8183
|
+
screen: "repo",
|
|
8184
|
+
ref: STATE.repoRef || "worktree",
|
|
8185
|
+
path: "",
|
|
8186
|
+
range: currentRange()
|
|
8187
|
+
});
|
|
8078
8188
|
}
|
|
8079
8189
|
if (link2.dataset.route === "diff") {
|
|
8080
8190
|
link2.href = buildRoute({ screen: "diff", range: currentRange() });
|
|
8081
8191
|
}
|
|
8082
8192
|
if (link2.dataset.route === "help") {
|
|
8083
|
-
link2.href = buildRoute({
|
|
8193
|
+
link2.href = buildRoute({
|
|
8194
|
+
screen: "help",
|
|
8195
|
+
lang: helpLanguageFromRoute(),
|
|
8196
|
+
section: helpSectionFromRoute(),
|
|
8197
|
+
range: currentRange()
|
|
8198
|
+
});
|
|
8084
8199
|
}
|
|
8085
8200
|
});
|
|
8086
8201
|
}
|
|
@@ -8119,7 +8234,12 @@
|
|
|
8119
8234
|
langSelect.appendChild(option);
|
|
8120
8235
|
});
|
|
8121
8236
|
langSelect.addEventListener("change", () => {
|
|
8122
|
-
setRoute({
|
|
8237
|
+
setRoute({
|
|
8238
|
+
screen: "help",
|
|
8239
|
+
lang: langSelect.value,
|
|
8240
|
+
section,
|
|
8241
|
+
range: currentRange()
|
|
8242
|
+
});
|
|
8123
8243
|
setPageMode();
|
|
8124
8244
|
renderHelpPage();
|
|
8125
8245
|
syncHeaderMenu();
|
|
@@ -8135,7 +8255,12 @@
|
|
|
8135
8255
|
button.className = helpSection === section ? "active" : "";
|
|
8136
8256
|
button.textContent = content.sections[helpSection].nav;
|
|
8137
8257
|
button.addEventListener("click", () => {
|
|
8138
|
-
setRoute({
|
|
8258
|
+
setRoute({
|
|
8259
|
+
screen: "help",
|
|
8260
|
+
lang,
|
|
8261
|
+
section: helpSection,
|
|
8262
|
+
range: currentRange()
|
|
8263
|
+
});
|
|
8139
8264
|
renderHelpPage();
|
|
8140
8265
|
syncHeaderMenu();
|
|
8141
8266
|
});
|
|
@@ -8265,7 +8390,10 @@
|
|
|
8265
8390
|
try {
|
|
8266
8391
|
const res = await fetch("/_open_path", {
|
|
8267
8392
|
method: "POST",
|
|
8268
|
-
headers: {
|
|
8393
|
+
headers: {
|
|
8394
|
+
"Content-Type": "application/json",
|
|
8395
|
+
"X-Code-Viewer-Action": "1"
|
|
8396
|
+
},
|
|
8269
8397
|
body: JSON.stringify({ path, kind })
|
|
8270
8398
|
});
|
|
8271
8399
|
if (!res.ok)
|
|
@@ -8370,7 +8498,12 @@
|
|
|
8370
8498
|
return dropPanel;
|
|
8371
8499
|
}
|
|
8372
8500
|
function repoRoute(ref, path) {
|
|
8373
|
-
return {
|
|
8501
|
+
return {
|
|
8502
|
+
screen: "repo",
|
|
8503
|
+
ref: ref || "worktree",
|
|
8504
|
+
path,
|
|
8505
|
+
range: currentRange()
|
|
8506
|
+
};
|
|
8374
8507
|
}
|
|
8375
8508
|
function wireRefSelectorInput(input, onPick) {
|
|
8376
8509
|
const wrap = input.closest("[data-ref-selector]");
|
|
@@ -8516,7 +8649,13 @@
|
|
|
8516
8649
|
setRoute(repoRoute(meta.ref, entry.path));
|
|
8517
8650
|
loadRepo();
|
|
8518
8651
|
} else if (entry.type === "blob") {
|
|
8519
|
-
setRoute({
|
|
8652
|
+
setRoute({
|
|
8653
|
+
screen: "file",
|
|
8654
|
+
path: entry.path,
|
|
8655
|
+
ref: meta.ref,
|
|
8656
|
+
view: "blob",
|
|
8657
|
+
range: currentRange()
|
|
8658
|
+
});
|
|
8520
8659
|
renderStandaloneSource({ path: entry.path, ref: meta.ref });
|
|
8521
8660
|
}
|
|
8522
8661
|
});
|
|
@@ -8553,7 +8692,13 @@
|
|
|
8553
8692
|
wrapper.appendChild(await renderMarkdownPreview(meta.readme.text, { path: meta.readme.path, ref: meta.ref }, {
|
|
8554
8693
|
syntaxHighlight: STATE.syntaxHighlight,
|
|
8555
8694
|
onNavigateMarkdown: (path, ref) => {
|
|
8556
|
-
setRoute({
|
|
8695
|
+
setRoute({
|
|
8696
|
+
screen: "file",
|
|
8697
|
+
path,
|
|
8698
|
+
ref,
|
|
8699
|
+
view: "blob",
|
|
8700
|
+
range: currentRange()
|
|
8701
|
+
});
|
|
8557
8702
|
renderStandaloneSource({ path, ref });
|
|
8558
8703
|
}
|
|
8559
8704
|
}));
|
|
@@ -8608,7 +8753,13 @@
|
|
|
8608
8753
|
loadRepo();
|
|
8609
8754
|
return;
|
|
8610
8755
|
}
|
|
8611
|
-
setRoute({
|
|
8756
|
+
setRoute({
|
|
8757
|
+
screen: "file",
|
|
8758
|
+
path: file.path,
|
|
8759
|
+
ref: normalizedRef,
|
|
8760
|
+
view: "blob",
|
|
8761
|
+
range: currentRange()
|
|
8762
|
+
});
|
|
8612
8763
|
renderStandaloneSource({ path: file.path, ref: normalizedRef });
|
|
8613
8764
|
});
|
|
8614
8765
|
REPO_SIDEBAR_REF = normalizedRef;
|
|
@@ -8668,7 +8819,9 @@
|
|
|
8668
8819
|
}, { rootMargin: "1200px 0px 1600px 0px" });
|
|
8669
8820
|
document.querySelectorAll(".gdp-file-shell.pending").forEach((c2) => lazyObserver.observe(c2));
|
|
8670
8821
|
}
|
|
8671
|
-
window.addEventListener("scroll", () => enqueueInitialLoads(), {
|
|
8822
|
+
window.addEventListener("scroll", () => enqueueInitialLoads(), {
|
|
8823
|
+
passive: true
|
|
8824
|
+
});
|
|
8672
8825
|
window.addEventListener("resize", () => {
|
|
8673
8826
|
enqueueInitialLoads();
|
|
8674
8827
|
syncSidebarHeaderHeight();
|
|
@@ -8757,7 +8910,12 @@
|
|
|
8757
8910
|
openFileBtn.title = "Open this file in the virtualized source viewer";
|
|
8758
8911
|
openFileBtn.addEventListener("click", () => {
|
|
8759
8912
|
const target = fileSourceTarget(file);
|
|
8760
|
-
setRoute({
|
|
8913
|
+
setRoute({
|
|
8914
|
+
screen: "file",
|
|
8915
|
+
path: target.path,
|
|
8916
|
+
ref: target.ref,
|
|
8917
|
+
range: currentRange()
|
|
8918
|
+
});
|
|
8761
8919
|
applySourceRouteToShell();
|
|
8762
8920
|
});
|
|
8763
8921
|
const fullBtn = document.createElement("button");
|
|
@@ -8916,7 +9074,11 @@
|
|
|
8916
9074
|
if (!info)
|
|
8917
9075
|
return;
|
|
8918
9076
|
const txt = (info.textContent || "").trim();
|
|
8919
|
-
arr.push({
|
|
9077
|
+
arr.push({
|
|
9078
|
+
tr,
|
|
9079
|
+
info,
|
|
9080
|
+
hunk: parseHunkHeader(txt)
|
|
9081
|
+
});
|
|
8920
9082
|
});
|
|
8921
9083
|
perTable.push(arr);
|
|
8922
9084
|
});
|
|
@@ -9161,7 +9323,13 @@
|
|
|
9161
9323
|
});
|
|
9162
9324
|
};
|
|
9163
9325
|
rows.forEach((row) => {
|
|
9164
|
-
row.ln.appendChild(createExpandStack([
|
|
9326
|
+
row.ln.appendChild(createExpandStack([
|
|
9327
|
+
{
|
|
9328
|
+
direction: "down",
|
|
9329
|
+
title: "Show more lines",
|
|
9330
|
+
onClick: fetchAndInsert
|
|
9331
|
+
}
|
|
9332
|
+
]));
|
|
9165
9333
|
});
|
|
9166
9334
|
syncExpandRowHeights(rows.map((row) => row.tr), rows[0].tr);
|
|
9167
9335
|
}
|
|
@@ -9309,7 +9477,23 @@
|
|
|
9309
9477
|
card.appendChild(view);
|
|
9310
9478
|
}
|
|
9311
9479
|
function isPreviewableSource(path) {
|
|
9312
|
-
return /\.(md|markdown|mdown|mkdn|mdx)$/i.test(path);
|
|
9480
|
+
return /\.(md|markdown|mdown|mkdn|mdx|html|htm)$/i.test(path);
|
|
9481
|
+
}
|
|
9482
|
+
function sourcePreviewKind(path) {
|
|
9483
|
+
if (/\.(md|markdown|mdown|mkdn|mdx)$/i.test(path))
|
|
9484
|
+
return "markdown";
|
|
9485
|
+
if (/\.(html|htm)$/i.test(path))
|
|
9486
|
+
return "html";
|
|
9487
|
+
return null;
|
|
9488
|
+
}
|
|
9489
|
+
function renderHtmlPreview(target, html) {
|
|
9490
|
+
const preview = document.createElement("div");
|
|
9491
|
+
preview.className = "gdp-html-preview";
|
|
9492
|
+
const frame = document.createElement("iframe");
|
|
9493
|
+
frame.title = target.path + " preview";
|
|
9494
|
+
frame.srcdoc = html;
|
|
9495
|
+
preview.appendChild(frame);
|
|
9496
|
+
return preview;
|
|
9313
9497
|
}
|
|
9314
9498
|
const EXT_TO_LANG = {
|
|
9315
9499
|
js: "javascript",
|
|
@@ -9753,6 +9937,7 @@
|
|
|
9753
9937
|
if (signal?.aborted)
|
|
9754
9938
|
return false;
|
|
9755
9939
|
const previewable = isPreviewableSource(target.path);
|
|
9940
|
+
const previewKind = sourcePreviewKind(target.path);
|
|
9756
9941
|
const tabsHost = card.querySelector(".gdp-file-detail-tabs");
|
|
9757
9942
|
if (usesVirtualSource) {
|
|
9758
9943
|
const virtualCode = renderVirtualSource(target, textValue, lines, hljsRef, lang);
|
|
@@ -9762,11 +9947,17 @@
|
|
|
9762
9947
|
tabsHost.hidden = false;
|
|
9763
9948
|
tabsHost.replaceChildren(tabs2);
|
|
9764
9949
|
}
|
|
9765
|
-
const preview = await renderMarkdownPreview(textValue, target, {
|
|
9950
|
+
const preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await renderMarkdownPreview(textValue, target, {
|
|
9766
9951
|
syntaxHighlight: STATE.syntaxHighlight,
|
|
9767
9952
|
signal,
|
|
9768
9953
|
onNavigateMarkdown: (path, ref) => {
|
|
9769
|
-
setRoute({
|
|
9954
|
+
setRoute({
|
|
9955
|
+
screen: "file",
|
|
9956
|
+
path,
|
|
9957
|
+
ref,
|
|
9958
|
+
view: "blob",
|
|
9959
|
+
range: currentRange()
|
|
9960
|
+
});
|
|
9770
9961
|
renderStandaloneSource({ path, ref });
|
|
9771
9962
|
}
|
|
9772
9963
|
});
|
|
@@ -9848,11 +10039,17 @@
|
|
|
9848
10039
|
tabsHost.replaceChildren(tabs);
|
|
9849
10040
|
}
|
|
9850
10041
|
if (previewable) {
|
|
9851
|
-
const preview = await renderMarkdownPreview(textValue, target, {
|
|
10042
|
+
const preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await renderMarkdownPreview(textValue, target, {
|
|
9852
10043
|
syntaxHighlight: STATE.syntaxHighlight,
|
|
9853
10044
|
signal,
|
|
9854
10045
|
onNavigateMarkdown: (path, ref) => {
|
|
9855
|
-
setRoute({
|
|
10046
|
+
setRoute({
|
|
10047
|
+
screen: "file",
|
|
10048
|
+
path,
|
|
10049
|
+
ref,
|
|
10050
|
+
view: "blob",
|
|
10051
|
+
range: currentRange()
|
|
10052
|
+
});
|
|
9856
10053
|
renderStandaloneSource({ path, ref });
|
|
9857
10054
|
}
|
|
9858
10055
|
});
|
|
@@ -10229,7 +10426,10 @@
|
|
|
10229
10426
|
const activeRange = search?.activeRange() || null;
|
|
10230
10427
|
if (appendVirtualSourceLineCode(code2, line, searchQuery, activeRange, index + 1)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
|
|
10231
10428
|
try {
|
|
10232
|
-
code2.innerHTML = hljsRef.highlight(line, {
|
|
10429
|
+
code2.innerHTML = hljsRef.highlight(line, {
|
|
10430
|
+
language: lang,
|
|
10431
|
+
ignoreIllegals: true
|
|
10432
|
+
}).value;
|
|
10233
10433
|
code2.classList.add("hljs");
|
|
10234
10434
|
} catch {
|
|
10235
10435
|
code2.textContent = line;
|
|
@@ -10391,7 +10591,10 @@
|
|
|
10391
10591
|
code2.textContent = "";
|
|
10392
10592
|
} else if (appendVirtualSourceLineCode(code2, line, search?.query() || "", search?.activeRange() || null, lineNumber)) {} else if (hljsRef && hljsRef.highlight && lang && line.length <= VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH && (!hljsRef.getLanguage || hljsRef.getLanguage(lang))) {
|
|
10393
10593
|
try {
|
|
10394
|
-
code2.innerHTML = hljsRef.highlight(line, {
|
|
10594
|
+
code2.innerHTML = hljsRef.highlight(line, {
|
|
10595
|
+
language: lang,
|
|
10596
|
+
ignoreIllegals: true
|
|
10597
|
+
}).value;
|
|
10395
10598
|
code2.classList.add("hljs");
|
|
10396
10599
|
} catch {
|
|
10397
10600
|
code2.textContent = line;
|
|
@@ -10420,7 +10623,9 @@
|
|
|
10420
10623
|
let done = false;
|
|
10421
10624
|
while (!done && matches.length < 5000) {
|
|
10422
10625
|
const endLine = startLine + VIRTUAL_SOURCE_PAGE_SIZE - 1;
|
|
10423
|
-
const data = await trackLoad(fetch(buildFileRangeUrl(target, startLine, endLine), {
|
|
10626
|
+
const data = await trackLoad(fetch(buildFileRangeUrl(target, startLine, endLine), {
|
|
10627
|
+
signal: matchSignal
|
|
10628
|
+
}).then((res) => {
|
|
10424
10629
|
if (!res.ok)
|
|
10425
10630
|
throw new Error("file range failed");
|
|
10426
10631
|
return res.json();
|
|
@@ -10431,7 +10636,11 @@
|
|
|
10431
10636
|
const lineNumber = data.start + index;
|
|
10432
10637
|
lines.set(lineNumber, lineValue);
|
|
10433
10638
|
for (const range of virtualSourceSearchRanges(lineValue, query)) {
|
|
10434
|
-
matches.push({
|
|
10639
|
+
matches.push({
|
|
10640
|
+
line: lineNumber,
|
|
10641
|
+
start: range.start,
|
|
10642
|
+
end: range.end
|
|
10643
|
+
});
|
|
10435
10644
|
if (matches.length >= 5000)
|
|
10436
10645
|
break;
|
|
10437
10646
|
}
|
|
@@ -10491,7 +10700,9 @@
|
|
|
10491
10700
|
const hljsRef = STATE.syntaxHighlight ? await loadSyntaxHighlighter() : null;
|
|
10492
10701
|
if (signal?.aborted)
|
|
10493
10702
|
return false;
|
|
10494
|
-
const initial = await trackLoad(fetch(buildFileRangeUrl(target, initialStart, initialEnd), {
|
|
10703
|
+
const initial = await trackLoad(fetch(buildFileRangeUrl(target, initialStart, initialEnd), {
|
|
10704
|
+
signal
|
|
10705
|
+
}).then((res) => res.ok ? res.json() : null));
|
|
10495
10706
|
if (!initial)
|
|
10496
10707
|
return false;
|
|
10497
10708
|
if (signal?.aborted)
|
|
@@ -10942,7 +11153,12 @@
|
|
|
10942
11153
|
viewFile.addEventListener("click", (e2) => {
|
|
10943
11154
|
e2.stopPropagation();
|
|
10944
11155
|
const target = fileSourceTarget(file);
|
|
10945
|
-
setRoute({
|
|
11156
|
+
setRoute({
|
|
11157
|
+
screen: "file",
|
|
11158
|
+
path: target.path,
|
|
11159
|
+
ref: target.ref,
|
|
11160
|
+
range: currentRange()
|
|
11161
|
+
});
|
|
10946
11162
|
applySourceRouteToShell();
|
|
10947
11163
|
});
|
|
10948
11164
|
header.appendChild(viewFile);
|
|
@@ -11053,7 +11269,10 @@
|
|
|
11053
11269
|
if (text2.length === 0)
|
|
11054
11270
|
return;
|
|
11055
11271
|
try {
|
|
11056
|
-
s2.innerHTML = hljsRef.highlight(text2, {
|
|
11272
|
+
s2.innerHTML = hljsRef.highlight(text2, {
|
|
11273
|
+
language: lang,
|
|
11274
|
+
ignoreIllegals: true
|
|
11275
|
+
}).value;
|
|
11057
11276
|
if (!s2.classList.contains("hljs"))
|
|
11058
11277
|
s2.classList.add("hljs");
|
|
11059
11278
|
} catch (_) {}
|
|
@@ -11084,7 +11303,10 @@
|
|
|
11084
11303
|
if (text2.length === 0)
|
|
11085
11304
|
continue;
|
|
11086
11305
|
try {
|
|
11087
|
-
s2.innerHTML = hljsRef.highlight(text2, {
|
|
11306
|
+
s2.innerHTML = hljsRef.highlight(text2, {
|
|
11307
|
+
language: lang,
|
|
11308
|
+
ignoreIllegals: true
|
|
11309
|
+
}).value;
|
|
11088
11310
|
if (!s2.classList.contains("hljs"))
|
|
11089
11311
|
s2.classList.add("hljs");
|
|
11090
11312
|
} catch (_) {}
|
|
@@ -11729,7 +11951,17 @@
|
|
|
11729
11951
|
if (!query.trim()) {
|
|
11730
11952
|
const base2 = source === "diff" ? state.diffSnapshot.map((file) => {
|
|
11731
11953
|
const target = fileSourceTarget(file);
|
|
11732
|
-
return {
|
|
11954
|
+
return {
|
|
11955
|
+
kind: "file",
|
|
11956
|
+
path: file.path,
|
|
11957
|
+
old_path: file.old_path,
|
|
11958
|
+
displayPath: file.path,
|
|
11959
|
+
ref: paletteRef(source),
|
|
11960
|
+
targetPath: target.path,
|
|
11961
|
+
targetRef: target.ref,
|
|
11962
|
+
source,
|
|
11963
|
+
ranges: []
|
|
11964
|
+
};
|
|
11733
11965
|
}) : [];
|
|
11734
11966
|
state.items = limitPaletteResults(base2);
|
|
11735
11967
|
state.selected = state.items.length ? 0 : -1;
|
|
@@ -11795,7 +12027,9 @@
|
|
|
11795
12027
|
}
|
|
11796
12028
|
const controller = new AbortController;
|
|
11797
12029
|
state.controller = controller;
|
|
11798
|
-
trackLoad(fetch("/_grep?" + params.toString(), {
|
|
12030
|
+
trackLoad(fetch("/_grep?" + params.toString(), {
|
|
12031
|
+
signal: controller.signal
|
|
12032
|
+
}).then((r2) => {
|
|
11799
12033
|
if (!r2.ok)
|
|
11800
12034
|
throw new Error("grep failed");
|
|
11801
12035
|
return r2.json();
|
|
@@ -11839,22 +12073,45 @@
|
|
|
11839
12073
|
if (item.kind === "file") {
|
|
11840
12074
|
if (item.source === "diff") {
|
|
11841
12075
|
if (STATE.route.screen === "file") {
|
|
11842
|
-
setRoute({
|
|
12076
|
+
setRoute({
|
|
12077
|
+
screen: "file",
|
|
12078
|
+
path: item.targetPath || item.path,
|
|
12079
|
+
ref: item.targetRef || item.ref,
|
|
12080
|
+
range: currentRange()
|
|
12081
|
+
});
|
|
11843
12082
|
applySourceRouteToShell();
|
|
11844
12083
|
} else {
|
|
11845
12084
|
scrollToFile(item.path);
|
|
11846
12085
|
}
|
|
11847
12086
|
} else {
|
|
11848
|
-
setRoute({
|
|
12087
|
+
setRoute({
|
|
12088
|
+
screen: "file",
|
|
12089
|
+
path: item.path,
|
|
12090
|
+
ref: item.ref,
|
|
12091
|
+
view: "blob",
|
|
12092
|
+
range: currentRange()
|
|
12093
|
+
});
|
|
11849
12094
|
renderStandaloneSource({ path: item.path, ref: item.ref });
|
|
11850
12095
|
}
|
|
11851
12096
|
return;
|
|
11852
12097
|
}
|
|
11853
12098
|
if (item.source === "diff") {
|
|
11854
|
-
setRoute({
|
|
12099
|
+
setRoute({
|
|
12100
|
+
screen: "diff",
|
|
12101
|
+
range: currentRange(),
|
|
12102
|
+
path: item.path,
|
|
12103
|
+
line: item.line
|
|
12104
|
+
});
|
|
11855
12105
|
scrollToFile(item.path, item.line);
|
|
11856
12106
|
} else {
|
|
11857
|
-
setRoute({
|
|
12107
|
+
setRoute({
|
|
12108
|
+
screen: "file",
|
|
12109
|
+
path: item.path,
|
|
12110
|
+
ref: item.ref,
|
|
12111
|
+
view: "blob",
|
|
12112
|
+
line: item.line,
|
|
12113
|
+
range: currentRange()
|
|
12114
|
+
});
|
|
11858
12115
|
renderStandaloneSource({ path: item.path, ref: item.ref });
|
|
11859
12116
|
}
|
|
11860
12117
|
}
|
|
@@ -11991,7 +12248,10 @@
|
|
|
11991
12248
|
else if (scope === "sidebar")
|
|
11992
12249
|
moveActiveSidebarToEdge(edge);
|
|
11993
12250
|
else
|
|
11994
|
-
window.scrollTo({
|
|
12251
|
+
window.scrollTo({
|
|
12252
|
+
top: edge === "top" ? 0 : Math.max(document.documentElement.scrollHeight, document.body.scrollHeight),
|
|
12253
|
+
behavior: "auto"
|
|
12254
|
+
});
|
|
11995
12255
|
return true;
|
|
11996
12256
|
}
|
|
11997
12257
|
if (action === "layout-unified") {
|
|
@@ -12041,7 +12301,9 @@
|
|
|
12041
12301
|
function handleVirtualSourcePagingKeydown(e2) {
|
|
12042
12302
|
handleVirtualSourcePagingKey(e2, e2.target);
|
|
12043
12303
|
}
|
|
12044
|
-
document.addEventListener("keydown", handleVirtualSourcePagingKeydown, {
|
|
12304
|
+
document.addEventListener("keydown", handleVirtualSourcePagingKeydown, {
|
|
12305
|
+
capture: true
|
|
12306
|
+
});
|
|
12045
12307
|
document.addEventListener("keydown", (e2) => {
|
|
12046
12308
|
if (e2.__gdpVirtualSourcePagingHandled)
|
|
12047
12309
|
return;
|
|
@@ -12145,7 +12407,12 @@
|
|
|
12145
12407
|
if (STATE.route.screen === "file") {
|
|
12146
12408
|
setRoute({ screen: "file", path: STATE.route.path, ref: STATE.route.ref, range }, true);
|
|
12147
12409
|
} else if (STATE.route.screen === "help") {
|
|
12148
|
-
setRoute({
|
|
12410
|
+
setRoute({
|
|
12411
|
+
screen: "help",
|
|
12412
|
+
lang: helpLanguageFromRoute(),
|
|
12413
|
+
section: helpSectionFromRoute(),
|
|
12414
|
+
range
|
|
12415
|
+
}, true);
|
|
12149
12416
|
renderHelpPage();
|
|
12150
12417
|
} else {
|
|
12151
12418
|
setRoute({ screen: "diff", range }, true);
|
|
@@ -12154,7 +12421,12 @@
|
|
|
12154
12421
|
}
|
|
12155
12422
|
syncRefInputs();
|
|
12156
12423
|
syncHeaderMenu();
|
|
12157
|
-
const REFS = {
|
|
12424
|
+
const REFS = {
|
|
12425
|
+
branches: [],
|
|
12426
|
+
tags: [],
|
|
12427
|
+
commits: [],
|
|
12428
|
+
current: ""
|
|
12429
|
+
};
|
|
12158
12430
|
const popover = $("#ref-popover");
|
|
12159
12431
|
const popBody = popover.querySelector(".rp-body");
|
|
12160
12432
|
const popSearch = popover.querySelector(".rp-search");
|
|
@@ -12258,7 +12530,13 @@
|
|
|
12258
12530
|
wireRefSelectorInput($("#repo-target"), (ref) => {
|
|
12259
12531
|
if (STATE.route.screen !== "file")
|
|
12260
12532
|
return;
|
|
12261
|
-
setRoute({
|
|
12533
|
+
setRoute({
|
|
12534
|
+
screen: "file",
|
|
12535
|
+
path: STATE.route.path,
|
|
12536
|
+
ref,
|
|
12537
|
+
view: "blob",
|
|
12538
|
+
range: currentRange()
|
|
12539
|
+
});
|
|
12262
12540
|
renderStandaloneSource({ path: STATE.route.path, ref });
|
|
12263
12541
|
});
|
|
12264
12542
|
popSearch.addEventListener("input", () => buildPopBody(popSearch.value));
|