@youtyan/code-viewer 0.8.7 → 0.8.9
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 +16 -4
- package/dist/code-viewer.js +3 -2
- package/package.json +1 -1
- package/web/app.js +711 -287
- package/web/index.html +10 -9
- package/web/style.css +1548 -366
package/web/app.js
CHANGED
|
@@ -445,15 +445,47 @@ ${lines.join(`
|
|
|
445
445
|
]
|
|
446
446
|
};
|
|
447
447
|
}
|
|
448
|
-
function
|
|
448
|
+
function gdscriptLanguageDefinition(hljs) {
|
|
449
|
+
const api = hljs;
|
|
450
|
+
return {
|
|
451
|
+
name: "GDScript",
|
|
452
|
+
aliases: ["gd"],
|
|
453
|
+
keywords: {
|
|
454
|
+
keyword: "and as assert await break breakpoint class class_name const continue elif else enum extends for func if in is match not or pass return self signal static super var void when while yield",
|
|
455
|
+
literal: "true false null PI TAU INF NAN",
|
|
456
|
+
built_in: "print printerr printraw print_rich print_debug push_error push_warning preload load range len abs absf absi sign floor ceil round clamp clampf clampi lerp lerpf min max pow sqrt randf randi randf_range randi_range randomize str int float bool typeof type_exists is_instance_valid Vector2 Vector2i Vector3 Vector3i Vector4 Vector4i Rect2 Rect2i Transform2D Transform3D Basis Quaternion Plane AABB Color NodePath StringName Callable Signal Array Dictionary PackedByteArray PackedInt32Array PackedInt64Array PackedFloat32Array PackedFloat64Array PackedStringArray PackedVector2Array PackedVector3Array PackedColorArray"
|
|
457
|
+
},
|
|
458
|
+
contains: [
|
|
459
|
+
lineComment(api, "#"),
|
|
460
|
+
{
|
|
461
|
+
scope: "string",
|
|
462
|
+
begin: '"""',
|
|
463
|
+
end: '"""'
|
|
464
|
+
},
|
|
465
|
+
api.QUOTE_STRING_MODE || { scope: "string", begin: '"', end: '"' },
|
|
466
|
+
{ scope: "string", begin: "'", end: "'" },
|
|
467
|
+
{ scope: "meta", begin: "@[A-Za-z_]\\w*" },
|
|
468
|
+
{ scope: "symbol", begin: "[$%][A-Za-z_/][\\w/]*" },
|
|
469
|
+
api.NUMBER_MODE || { scope: "number", begin: "\\b\\d+(\\.\\d+)?\\b" },
|
|
470
|
+
{ scope: "function", begin: "\\b[A-Za-z_]\\w*(?=\\()" }
|
|
471
|
+
]
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
function ensureHighlightLanguage(hljsRef, name, definition) {
|
|
449
475
|
if (!hljsRef?.registerLanguage)
|
|
450
476
|
return;
|
|
451
|
-
if (hljsRef.getLanguage?.(
|
|
477
|
+
if (hljsRef.getLanguage?.(name))
|
|
452
478
|
return;
|
|
453
479
|
try {
|
|
454
|
-
hljsRef.registerLanguage(
|
|
480
|
+
hljsRef.registerLanguage(name, definition);
|
|
455
481
|
} catch {}
|
|
456
482
|
}
|
|
483
|
+
function ensureTerraformHighlightLanguage(hljsRef) {
|
|
484
|
+
ensureHighlightLanguage(hljsRef, "terraform", terraformLanguageDefinition);
|
|
485
|
+
}
|
|
486
|
+
function ensureGdscriptHighlightLanguage(hljsRef) {
|
|
487
|
+
ensureHighlightLanguage(hljsRef, "gdscript", gdscriptLanguageDefinition);
|
|
488
|
+
}
|
|
457
489
|
|
|
458
490
|
// web-src/core/icons.ts
|
|
459
491
|
var FOLDER_ICON_PATHS = {
|
|
@@ -513,6 +545,8 @@ ${lines.join(`
|
|
|
513
545
|
];
|
|
514
546
|
var X_16_PATH = "M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z";
|
|
515
547
|
var SYNC_16_PATH = "M1.705 8.005a.75.75 0 0 1 .834.656 5.5 5.5 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.002 7.002 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834ZM8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.002 7.002 0 0 1 14.95 7.16a.75.75 0 0 1-1.49.178A5.5 5.5 0 0 0 8 2.5Z";
|
|
548
|
+
var ARROW_RIGHT_16_PATH = "M8.22 2.97a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l2.97-2.97H3.75a.75.75 0 0 1 0-1.5h7.44L8.22 4.03a.75.75 0 0 1 0-1.06Z";
|
|
549
|
+
var UNDO_16_PATH = "M1.22 6.28a.749.749 0 0 1 0-1.06l3.5-3.5a.749.749 0 1 1 1.06 1.06L3.561 5h7.188l.001.007L10.749 5c.058 0 .116.007.171.019A4.501 4.501 0 0 1 10.5 14H8.796a.75.75 0 0 1 0-1.5H10.5a3 3 0 1 0 0-6H3.561L5.78 8.72a.749.749 0 1 1-1.06 1.06l-3.5-3.5Z";
|
|
516
550
|
function iconSvg(className, paths) {
|
|
517
551
|
const pathList = Array.isArray(paths) ? paths : [paths];
|
|
518
552
|
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>";
|
|
@@ -522,6 +556,9 @@ ${lines.join(`
|
|
|
522
556
|
var GRABBER_16_PATH = "M10 13h4v-2h-4v2Zm-8 0h4v-2H2v2Zm8-6h4V5h-4v2ZM2 7h4V5H2v2Zm8-6v2h4V1h-4ZM2 3h4V1H2v2Z";
|
|
523
557
|
var PULSE_16_PATH = "M6 2c.306 0 .582.187.696.471L10 10.731l1.304-3.26A.751.751 0 0 1 12 7h3.25a.75.75 0 0 1 0 1.5h-2.742l-1.812 4.528a.751.751 0 0 1-1.392 0L6 4.77 4.696 8.03A.75.75 0 0 1 4 8.5H.75a.75.75 0 0 1 0-1.5h2.742l1.812-4.529A.751.751 0 0 1 6 2Z";
|
|
524
558
|
var MOON_16_PATH = "M9.598 1.591a.749.749 0 0 1 .785-.175 7.001 7.001 0 1 1-8.967 8.967.75.75 0 0 1 .961-.96 5.5 5.5 0 0 0 7.046-7.046.75.75 0 0 1 .175-.786Zm1.616 1.945a7 7 0 0 1-7.678 7.678 5.499 5.499 0 1 0 7.678-7.678Z";
|
|
559
|
+
var QUESTION_16_PATH = "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.92 6.085h.001a.749.749 0 1 1-1.342-.67c.169-.339.436-.701.849-.977C6.845 4.16 7.369 4 8 4a2.756 2.756 0 0 1 1.637.525c.503.377.863.965.863 1.725 0 .448-.115.83-.329 1.15-.205.307-.47.513-.692.662-.109.072-.22.138-.313.195l-.006.004a6.24 6.24 0 0 0-.26.16.952.952 0 0 0-.276.245.75.75 0 0 1-1.248-.832c.184-.264.42-.489.692-.661.103-.067.207-.132.313-.195l.007-.004c.1-.061.182-.11.258-.161a.969.969 0 0 0 .277-.245C8.96 6.514 9 6.427 9 6.25a.612.612 0 0 0-.262-.525A1.27 1.27 0 0 0 8 5.5c-.369 0-.595.09-.74.187a1.01 1.01 0 0 0-.34.398ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z";
|
|
560
|
+
var MARK_GITHUB_16_PATH = "M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656";
|
|
561
|
+
var BOOK_16_PATH = "M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z";
|
|
525
562
|
var SEARCH_16_PATH = "M10.68 11.74a6 6 0 0 1-7.917-8.984 6 6 0 0 1 8.997 7.905l3.05 3.05a.75.75 0 1 1-1.06 1.06l-3.07-3.03ZM11.5 7a4.499 4.499 0 1 1-8.997 0A4.499 4.499 0 0 1 11.5 7Z";
|
|
526
563
|
var DOWNLOAD_16_PATHS = [
|
|
527
564
|
"M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z",
|
|
@@ -778,6 +815,50 @@ ${lines.join(`
|
|
|
778
815
|
};
|
|
779
816
|
}
|
|
780
817
|
|
|
818
|
+
// web-src/core/repository-web-url.ts
|
|
819
|
+
function encodePath(value) {
|
|
820
|
+
return value.split("/").filter(Boolean).map((part) => encodeURIComponent(part)).join("/");
|
|
821
|
+
}
|
|
822
|
+
function resolvedRef(ref, fallbackRef) {
|
|
823
|
+
if (!ref || ref === "worktree" || ref === "HEAD") {
|
|
824
|
+
return fallbackRef || "HEAD";
|
|
825
|
+
}
|
|
826
|
+
return ref;
|
|
827
|
+
}
|
|
828
|
+
function buildRepositoryWebTarget(repoWebUrl, options) {
|
|
829
|
+
if (!repoWebUrl)
|
|
830
|
+
return null;
|
|
831
|
+
let remote;
|
|
832
|
+
try {
|
|
833
|
+
remote = new URL(repoWebUrl);
|
|
834
|
+
} catch {
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
837
|
+
if (remote.protocol !== "http:" && remote.protocol !== "https:")
|
|
838
|
+
return null;
|
|
839
|
+
remote.search = "";
|
|
840
|
+
remote.hash = "";
|
|
841
|
+
remote.pathname = remote.pathname.replace(/\/+$/, "");
|
|
842
|
+
const base = remote.toString().replace(/\/$/, "");
|
|
843
|
+
if (remote.hostname.toLowerCase() !== "github.com") {
|
|
844
|
+
return { url: base, provider: "web" };
|
|
845
|
+
}
|
|
846
|
+
const ref = encodePath(resolvedRef(options.ref, options.fallbackRef));
|
|
847
|
+
const path = encodePath(options.path || "");
|
|
848
|
+
if (!ref || options.kind === "blob" && !path) {
|
|
849
|
+
return { url: base, provider: "github" };
|
|
850
|
+
}
|
|
851
|
+
const pathSuffix = path ? `/${path}` : "";
|
|
852
|
+
const target = `${base}/${options.kind}/${ref}${pathSuffix}`;
|
|
853
|
+
if (options.kind !== "blob" || !Number.isFinite(options.start) || !Number.isFinite(options.end)) {
|
|
854
|
+
return { url: target, provider: "github" };
|
|
855
|
+
}
|
|
856
|
+
const start = Math.max(1, Math.floor(Math.min(options.start, options.end)));
|
|
857
|
+
const end = Math.max(1, Math.floor(Math.max(options.start, options.end)));
|
|
858
|
+
const lineHash = start === end ? `#L${start}` : `#L${start}-L${end}`;
|
|
859
|
+
return { url: `${target}${lineHash}`, provider: "github" };
|
|
860
|
+
}
|
|
861
|
+
|
|
781
862
|
// web-src/core/routes.ts
|
|
782
863
|
function assertNever(value) {
|
|
783
864
|
throw new Error(`unhandled route: ${JSON.stringify(value)}`);
|
|
@@ -1005,7 +1086,7 @@ ${lines.join(`
|
|
|
1005
1086
|
}
|
|
1006
1087
|
case "journal": {
|
|
1007
1088
|
const params = new URLSearchParams;
|
|
1008
|
-
if (route.tab && route.tab !== "
|
|
1089
|
+
if (route.tab && route.tab !== "tasks")
|
|
1009
1090
|
params.set("tab", route.tab);
|
|
1010
1091
|
if (route.date)
|
|
1011
1092
|
params.set("date", route.date);
|
|
@@ -1265,7 +1346,8 @@ ${lines.join(`
|
|
|
1265
1346
|
cts: "typescript",
|
|
1266
1347
|
kts: "kotlin",
|
|
1267
1348
|
cxx: "cpp",
|
|
1268
|
-
hxx: "cpp"
|
|
1349
|
+
hxx: "cpp",
|
|
1350
|
+
gd: "gdscript"
|
|
1269
1351
|
};
|
|
1270
1352
|
var TEXT_SOURCE_EXTENSIONS = new Set([
|
|
1271
1353
|
...Object.keys(EXT_TO_LANG),
|
|
@@ -7536,6 +7618,8 @@ ${lines.join(`
|
|
|
7536
7618
|
tf: "terraform",
|
|
7537
7619
|
tfvars: "terraform",
|
|
7538
7620
|
hcl: "terraform",
|
|
7621
|
+
gd: "gdscript",
|
|
7622
|
+
godot: "gdscript",
|
|
7539
7623
|
yml: "yaml",
|
|
7540
7624
|
ts: "typescript",
|
|
7541
7625
|
tsx: "typescript",
|
|
@@ -7552,6 +7636,7 @@ ${lines.join(`
|
|
|
7552
7636
|
"csharp",
|
|
7553
7637
|
"css",
|
|
7554
7638
|
"dockerfile",
|
|
7639
|
+
"gdscript",
|
|
7555
7640
|
"go",
|
|
7556
7641
|
"graphql",
|
|
7557
7642
|
"html",
|
|
@@ -8573,16 +8658,19 @@ ${frontmatter.yaml}
|
|
|
8573
8658
|
|
|
8574
8659
|
// web-src/views/annotations-ui.ts
|
|
8575
8660
|
var ANNOTATION_SESSION_PARAM = "annotationSession";
|
|
8661
|
+
var ANNOTATION_PANEL_PARAM = "annotations";
|
|
8662
|
+
var ANNOTATION_ENTRY_PARAM = "annotation";
|
|
8576
8663
|
function createAnnotationsUi(deps) {
|
|
8577
8664
|
const { $ } = deps;
|
|
8578
8665
|
let ANNOTATIONS = { version: 1, sessions: [] };
|
|
8579
8666
|
let annotationFollow = deps.getAnnotationFollow();
|
|
8580
|
-
|
|
8667
|
+
const initialUrlParams = new URLSearchParams(window.location.search);
|
|
8668
|
+
let activeAnnotationId = initialUrlParams.get(ANNOTATION_ENTRY_PARAM);
|
|
8581
8669
|
let refreshAnnotationsInFlight = null;
|
|
8582
8670
|
let inlineAnnotationsMounted = false;
|
|
8583
8671
|
let databaseAnnotationsMounted = false;
|
|
8584
8672
|
let annotationPanelDismissed = false;
|
|
8585
|
-
let activeSessionId =
|
|
8673
|
+
let activeSessionId = initialUrlParams.get(ANNOTATION_SESSION_PARAM);
|
|
8586
8674
|
const annotationsChangedCallbacks = [];
|
|
8587
8675
|
function notifyAnnotationsChanged() {
|
|
8588
8676
|
for (const cb of annotationsChangedCallbacks)
|
|
@@ -8639,8 +8727,14 @@ ${frontmatter.yaml}
|
|
|
8639
8727
|
if (qhPanel)
|
|
8640
8728
|
qhPanel.hidden = true;
|
|
8641
8729
|
document.body.classList.remove("query-history-panel-open");
|
|
8730
|
+
} else if (activeAnnotationId) {
|
|
8731
|
+
activeAnnotationId = null;
|
|
8732
|
+
annotationDetail.hidden = true;
|
|
8733
|
+
updateActiveHighlights();
|
|
8734
|
+
syncInlineAnnotationActive();
|
|
8642
8735
|
}
|
|
8643
8736
|
deps.setAnnotationPanelOpenState(open);
|
|
8737
|
+
syncSessionUrl();
|
|
8644
8738
|
applyInlineAnnotations();
|
|
8645
8739
|
}
|
|
8646
8740
|
function annotationLineTarget(entry) {
|
|
@@ -8688,13 +8782,33 @@ ${frontmatter.yaml}
|
|
|
8688
8782
|
}
|
|
8689
8783
|
function withSessionParam(rawUrl) {
|
|
8690
8784
|
const url = new URL(rawUrl, window.location.origin);
|
|
8785
|
+
if (!annotationPanel.hidden)
|
|
8786
|
+
url.searchParams.set(ANNOTATION_PANEL_PARAM, "open");
|
|
8787
|
+
else
|
|
8788
|
+
url.searchParams.delete(ANNOTATION_PANEL_PARAM);
|
|
8691
8789
|
if (activeSessionId)
|
|
8692
8790
|
url.searchParams.set(ANNOTATION_SESSION_PARAM, activeSessionId);
|
|
8693
8791
|
else
|
|
8694
8792
|
url.searchParams.delete(ANNOTATION_SESSION_PARAM);
|
|
8793
|
+
if (activeAnnotationId)
|
|
8794
|
+
url.searchParams.set(ANNOTATION_ENTRY_PARAM, activeAnnotationId);
|
|
8795
|
+
else
|
|
8796
|
+
url.searchParams.delete(ANNOTATION_ENTRY_PARAM);
|
|
8695
8797
|
return url.pathname + url.search;
|
|
8696
8798
|
}
|
|
8697
|
-
function
|
|
8799
|
+
function createStepChip(entry, step) {
|
|
8800
|
+
const chip = document.createElement("button");
|
|
8801
|
+
chip.type = "button";
|
|
8802
|
+
chip.className = "gdp-annotation-step";
|
|
8803
|
+
chip.textContent = `${step.index + 1}/${step.total}`;
|
|
8804
|
+
chip.title = `open step ${step.index + 1} of ${step.total}`;
|
|
8805
|
+
chip.setAttribute("aria-label", `open annotation step ${step.index + 1} of ${step.total}`);
|
|
8806
|
+
chip.addEventListener("click", () => {
|
|
8807
|
+
openAnnotationEntry(entry.id);
|
|
8808
|
+
});
|
|
8809
|
+
return chip;
|
|
8810
|
+
}
|
|
8811
|
+
function buildInlineAnnotationRow(entry, colSpan, step) {
|
|
8698
8812
|
const tr = document.createElement("tr");
|
|
8699
8813
|
tr.className = "gdp-annotation-row";
|
|
8700
8814
|
tr.dataset.annotationId = entry.id;
|
|
@@ -8703,13 +8817,17 @@ ${frontmatter.yaml}
|
|
|
8703
8817
|
td.colSpan = colSpan;
|
|
8704
8818
|
const box = document.createElement("div");
|
|
8705
8819
|
box.className = "gdp-annotation-inline";
|
|
8820
|
+
const head = document.createElement("div");
|
|
8821
|
+
head.className = "gdp-annotation-inline-head";
|
|
8822
|
+
head.appendChild(createStepChip(entry, step));
|
|
8706
8823
|
if (entry.title) {
|
|
8707
8824
|
const heading2 = document.createElement("strong");
|
|
8708
8825
|
heading2.className = "gdp-annotation-inline-title";
|
|
8709
8826
|
heading2.textContent = entry.title;
|
|
8710
|
-
|
|
8827
|
+
head.appendChild(heading2);
|
|
8711
8828
|
}
|
|
8712
|
-
|
|
8829
|
+
head.appendChild(createCopyRefButton(entry, "gdp-annotation-inline-copy"));
|
|
8830
|
+
box.appendChild(head);
|
|
8713
8831
|
const markdown = document.createElement("div");
|
|
8714
8832
|
markdown.className = "gdp-annotation-inline-body";
|
|
8715
8833
|
ensureMarkdownHighlighter();
|
|
@@ -8719,7 +8837,7 @@ ${frontmatter.yaml}
|
|
|
8719
8837
|
tr.appendChild(td);
|
|
8720
8838
|
return tr;
|
|
8721
8839
|
}
|
|
8722
|
-
function buildDatabaseAnnotationBlock(entry) {
|
|
8840
|
+
function buildDatabaseAnnotationBlock(entry, step) {
|
|
8723
8841
|
const box = document.createElement("div");
|
|
8724
8842
|
box.className = "gdp-db-annotation-inline";
|
|
8725
8843
|
box.dataset.annotationId = entry.id;
|
|
@@ -8736,7 +8854,7 @@ ${frontmatter.yaml}
|
|
|
8736
8854
|
const location2 = document.createElement("span");
|
|
8737
8855
|
location2.className = "gdp-db-annotation-inline-location";
|
|
8738
8856
|
location2.textContent = annotationLocationLabel(entry);
|
|
8739
|
-
head.append(title, location2, createCopyRefButton(entry));
|
|
8857
|
+
head.append(createStepChip(entry, step), title, location2, createCopyRefButton(entry));
|
|
8740
8858
|
const markdown = document.createElement("div");
|
|
8741
8859
|
markdown.className = "gdp-db-annotation-inline-body";
|
|
8742
8860
|
ensureMarkdownHighlighter();
|
|
@@ -8763,7 +8881,10 @@ ${frontmatter.yaml}
|
|
|
8763
8881
|
strip.className = "gdp-db-annotation-strip";
|
|
8764
8882
|
strip.setAttribute("aria-label", "Datastore annotations");
|
|
8765
8883
|
for (const entry of matches) {
|
|
8766
|
-
strip.appendChild(buildDatabaseAnnotationBlock(entry
|
|
8884
|
+
strip.appendChild(buildDatabaseAnnotationBlock(entry, {
|
|
8885
|
+
index: session.entries.indexOf(entry),
|
|
8886
|
+
total: session.entries.length
|
|
8887
|
+
}));
|
|
8767
8888
|
}
|
|
8768
8889
|
root.prepend(strip);
|
|
8769
8890
|
databaseAnnotationsMounted = true;
|
|
@@ -8838,16 +8959,19 @@ ${frontmatter.yaml}
|
|
|
8838
8959
|
if (!session)
|
|
8839
8960
|
return;
|
|
8840
8961
|
let mountedInlineRows = false;
|
|
8841
|
-
|
|
8962
|
+
session.entries.forEach((entry, index) => {
|
|
8842
8963
|
if (entry.target?.kind === "database")
|
|
8843
|
-
|
|
8964
|
+
return;
|
|
8844
8965
|
const target = inlineAnnotationTargetRow(entry);
|
|
8845
8966
|
if (!target)
|
|
8846
|
-
|
|
8967
|
+
return;
|
|
8847
8968
|
let anchor = target;
|
|
8848
8969
|
while (anchor.nextElementSibling?.classList.contains("gdp-annotation-row"))
|
|
8849
8970
|
anchor = anchor.nextElementSibling;
|
|
8850
|
-
anchor.after(buildInlineAnnotationRow(entry, target.cells.length
|
|
8971
|
+
anchor.after(buildInlineAnnotationRow(entry, target.cells.length, {
|
|
8972
|
+
index,
|
|
8973
|
+
total: session.entries.length
|
|
8974
|
+
}));
|
|
8851
8975
|
const sibling = siblingSideRow(target);
|
|
8852
8976
|
if (sibling) {
|
|
8853
8977
|
let sibAnchor = sibling;
|
|
@@ -8856,7 +8980,7 @@ ${frontmatter.yaml}
|
|
|
8856
8980
|
sibAnchor.after(buildInlineSpacerRow(entry, sibling.cells.length));
|
|
8857
8981
|
}
|
|
8858
8982
|
mountedInlineRows = true;
|
|
8859
|
-
}
|
|
8983
|
+
});
|
|
8860
8984
|
inlineAnnotationsMounted = mountedInlineRows;
|
|
8861
8985
|
syncInlineAnnotationWidths();
|
|
8862
8986
|
}
|
|
@@ -8895,14 +9019,21 @@ ${frontmatter.yaml}
|
|
|
8895
9019
|
if (activeSessionId === sessionId)
|
|
8896
9020
|
return;
|
|
8897
9021
|
activeSessionId = sessionId;
|
|
9022
|
+
activeAnnotationId = null;
|
|
9023
|
+
annotationDetail.hidden = true;
|
|
8898
9024
|
syncSessionUrl();
|
|
8899
9025
|
updateActiveHighlights();
|
|
9026
|
+
syncInlineAnnotationActive();
|
|
8900
9027
|
applyInlineAnnotations();
|
|
8901
9028
|
notifyAnnotationsChanged();
|
|
8902
9029
|
}
|
|
8903
9030
|
function restoreSessionFromUrl() {
|
|
8904
|
-
|
|
9031
|
+
const params = new URLSearchParams(window.location.search);
|
|
9032
|
+
activeSessionId = params.get(ANNOTATION_SESSION_PARAM);
|
|
9033
|
+
activeAnnotationId = params.get(ANNOTATION_ENTRY_PARAM);
|
|
9034
|
+
setAnnotationPanelOpen(params.get(ANNOTATION_PANEL_PARAM) === "open" || !!activeAnnotationId);
|
|
8905
9035
|
renderAnnotationPanel();
|
|
9036
|
+
restoreAnnotationDetailFromState();
|
|
8906
9037
|
applyInlineAnnotations();
|
|
8907
9038
|
}
|
|
8908
9039
|
async function waitForAnnotationDiffTarget(entry) {
|
|
@@ -9007,9 +9138,8 @@ ${frontmatter.yaml}
|
|
|
9007
9138
|
syncSessionUrl();
|
|
9008
9139
|
}
|
|
9009
9140
|
renderAnnotationPanel();
|
|
9141
|
+
restoreAnnotationDetailFromState();
|
|
9010
9142
|
applyInlineAnnotations();
|
|
9011
|
-
if (activeAnnotationId && !findAnnotation(activeAnnotationId))
|
|
9012
|
-
hideAnnotationDetail();
|
|
9013
9143
|
notifyAnnotationsChanged();
|
|
9014
9144
|
}
|
|
9015
9145
|
async function postAnnotationAction(payload) {
|
|
@@ -9169,6 +9299,10 @@ ${frontmatter.yaml}
|
|
|
9169
9299
|
time.className = "annotation-session-time";
|
|
9170
9300
|
time.textContent = annotationTimeLabel(session.created_at);
|
|
9171
9301
|
time.title = session.created_at;
|
|
9302
|
+
const count = document.createElement("span");
|
|
9303
|
+
count.className = "annotation-session-count";
|
|
9304
|
+
count.textContent = String(session.entries.length);
|
|
9305
|
+
count.title = `${session.entries.length} steps`;
|
|
9172
9306
|
title.addEventListener("click", () => {
|
|
9173
9307
|
setActiveSession(session.id === activeSessionId ? null : session.id);
|
|
9174
9308
|
});
|
|
@@ -9204,7 +9338,7 @@ ${frontmatter.yaml}
|
|
|
9204
9338
|
return;
|
|
9205
9339
|
postAnnotationAction({ action: "delete", id: session.id });
|
|
9206
9340
|
});
|
|
9207
|
-
head.append(title, time, rename, del);
|
|
9341
|
+
head.append(title, count, time, rename, del);
|
|
9208
9342
|
sessionEl.appendChild(head);
|
|
9209
9343
|
const list2 = document.createElement("ol");
|
|
9210
9344
|
list2.className = "annotation-entries";
|
|
@@ -9263,6 +9397,7 @@ ${frontmatter.yaml}
|
|
|
9263
9397
|
function hideAnnotationDetail() {
|
|
9264
9398
|
activeAnnotationId = null;
|
|
9265
9399
|
annotationDetail.hidden = true;
|
|
9400
|
+
syncSessionUrl();
|
|
9266
9401
|
updateActiveHighlights();
|
|
9267
9402
|
syncInlineAnnotationActive();
|
|
9268
9403
|
}
|
|
@@ -9306,6 +9441,25 @@ ${frontmatter.yaml}
|
|
|
9306
9441
|
updateActiveHighlights();
|
|
9307
9442
|
syncInlineAnnotationActive();
|
|
9308
9443
|
}
|
|
9444
|
+
function restoreAnnotationDetailFromState() {
|
|
9445
|
+
if (!activeAnnotationId) {
|
|
9446
|
+
annotationDetail.hidden = true;
|
|
9447
|
+
updateActiveHighlights();
|
|
9448
|
+
syncInlineAnnotationActive();
|
|
9449
|
+
return;
|
|
9450
|
+
}
|
|
9451
|
+
const found = findAnnotation(activeAnnotationId);
|
|
9452
|
+
if (!found) {
|
|
9453
|
+
activeAnnotationId = null;
|
|
9454
|
+
annotationDetail.hidden = true;
|
|
9455
|
+
syncSessionUrl();
|
|
9456
|
+
updateActiveHighlights();
|
|
9457
|
+
syncInlineAnnotationActive();
|
|
9458
|
+
return;
|
|
9459
|
+
}
|
|
9460
|
+
activeSessionId = found.session.id;
|
|
9461
|
+
showAnnotationDetail(found.session, found.entry, found.index);
|
|
9462
|
+
}
|
|
9309
9463
|
function focusStandaloneSourceLines(card, entry) {
|
|
9310
9464
|
if (!entry.line)
|
|
9311
9465
|
return;
|
|
@@ -9505,7 +9659,7 @@ ${frontmatter.yaml}
|
|
|
9505
9659
|
if (persist)
|
|
9506
9660
|
deps.setAnnotationPanelWidth(clamped);
|
|
9507
9661
|
}
|
|
9508
|
-
if (deps.getAnnotationPanelOpen())
|
|
9662
|
+
if (initialUrlParams.get(ANNOTATION_PANEL_PARAM) === "open" || activeAnnotationId || deps.getAnnotationPanelOpen())
|
|
9509
9663
|
setAnnotationPanelOpen(true);
|
|
9510
9664
|
applyAnnotationPanelWidth(deps.getAnnotationPanelWidth() ?? ANNOTATION_PANEL_DEFAULT_WIDTH, false);
|
|
9511
9665
|
updateDatabaseCaptureButton();
|
|
@@ -9681,6 +9835,24 @@ ${frontmatter.yaml}
|
|
|
9681
9835
|
function isBlobOrBlameFileRoute(route) {
|
|
9682
9836
|
return route.screen === "file" && (route.view === "blob" || route.view === "blame");
|
|
9683
9837
|
}
|
|
9838
|
+
function fileRouteKeepingActiveView(currentRoute, target, range) {
|
|
9839
|
+
const base2 = {
|
|
9840
|
+
screen: "file",
|
|
9841
|
+
path: target.path,
|
|
9842
|
+
ref: target.ref,
|
|
9843
|
+
range
|
|
9844
|
+
};
|
|
9845
|
+
if (currentRoute.screen !== "file")
|
|
9846
|
+
return { ...base2, view: "blob" };
|
|
9847
|
+
if (currentRoute.view === "blame" || currentRoute.view === "history")
|
|
9848
|
+
return { ...base2, view: currentRoute.view };
|
|
9849
|
+
const keepPreview = currentRoute.view === "blob" && !!currentRoute.preview && (isPreviewableSource(target.path) || isMediaPreviewOnlySource(target.path));
|
|
9850
|
+
return {
|
|
9851
|
+
...base2,
|
|
9852
|
+
view: "blob",
|
|
9853
|
+
...keepPreview ? { preview: true } : {}
|
|
9854
|
+
};
|
|
9855
|
+
}
|
|
9684
9856
|
function createFileViewTabButton(deps, target, view, label, active) {
|
|
9685
9857
|
const btn = document.createElement("button");
|
|
9686
9858
|
btn.type = "button";
|
|
@@ -9786,6 +9958,9 @@ ${frontmatter.yaml}
|
|
|
9786
9958
|
name.appendChild(deps.createFileBreadcrumb(target.path, target.ref));
|
|
9787
9959
|
name.appendChild(createFilePathCopyButton(target));
|
|
9788
9960
|
header.appendChild(name);
|
|
9961
|
+
const repositoryWebLink = deps.createRepositoryWebLink?.(target);
|
|
9962
|
+
if (repositoryWebLink)
|
|
9963
|
+
header.appendChild(repositoryWebLink);
|
|
9789
9964
|
sticky.appendChild(header);
|
|
9790
9965
|
const tabsHost = document.createElement("div");
|
|
9791
9966
|
tabsHost.className = "gdp-file-detail-tabs";
|
|
@@ -9988,7 +10163,8 @@ ${frontmatter.yaml}
|
|
|
9988
10163
|
currentRange: deps.currentRange,
|
|
9989
10164
|
setRoute: deps.setRoute,
|
|
9990
10165
|
setPreferredSourceTab: deps.setPreferredSourceTab,
|
|
9991
|
-
createFileBreadcrumb: deps.createFileBreadcrumb
|
|
10166
|
+
createFileBreadcrumb: deps.createFileBreadcrumb,
|
|
10167
|
+
createRepositoryWebLink: deps.createRepositoryWebLink
|
|
9992
10168
|
}, target, "blame");
|
|
9993
10169
|
sticky.appendChild(buildLegend());
|
|
9994
10170
|
wrapper.appendChild(sticky);
|
|
@@ -9998,10 +10174,11 @@ ${frontmatter.yaml}
|
|
|
9998
10174
|
wrapper.appendChild(body);
|
|
9999
10175
|
card.appendChild(wrapper);
|
|
10000
10176
|
mountFileShellCard(deps, target, card);
|
|
10177
|
+
const sourceShikiLang = normalizeSourceShikiLang(deps.inferLang(target.path));
|
|
10001
10178
|
const [blameResp, srcText, highlighter] = await Promise.all([
|
|
10002
10179
|
fetchBlame(target, generation),
|
|
10003
10180
|
fetchSource(target, base2),
|
|
10004
|
-
deps.getSyntaxHighlight() ? deps.loadSourceShikiHighlighter() : Promise.resolve(null)
|
|
10181
|
+
deps.getSyntaxHighlight() && sourceShikiLang ? deps.loadSourceShikiHighlighter(sourceShikiLang) : Promise.resolve(null)
|
|
10005
10182
|
]);
|
|
10006
10183
|
if (generation !== activeGeneration)
|
|
10007
10184
|
return;
|
|
@@ -17931,6 +18108,23 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
17931
18108
|
spacer.className = "db-grid-spacer";
|
|
17932
18109
|
const body = document.createElement("div");
|
|
17933
18110
|
body.className = "db-grid-body";
|
|
18111
|
+
body.addEventListener("mouseover", (e2) => {
|
|
18112
|
+
const cell = e2.target?.closest(".db-grid-cell");
|
|
18113
|
+
if (!cell || !body.contains(cell))
|
|
18114
|
+
return;
|
|
18115
|
+
if (cell.dataset.gridTooltip) {
|
|
18116
|
+
delete cell.dataset.gridTooltip;
|
|
18117
|
+
cell.removeAttribute("title");
|
|
18118
|
+
}
|
|
18119
|
+
if (cell.title)
|
|
18120
|
+
return;
|
|
18121
|
+
if (cell.querySelector("input, textarea, select"))
|
|
18122
|
+
return;
|
|
18123
|
+
if (cell.scrollWidth > cell.clientWidth + 1) {
|
|
18124
|
+
cell.title = cell.textContent ?? "";
|
|
18125
|
+
cell.dataset.gridTooltip = "1";
|
|
18126
|
+
}
|
|
18127
|
+
});
|
|
17934
18128
|
const filteredEmpty = document.createElement("div");
|
|
17935
18129
|
filteredEmpty.className = "db-pane-empty";
|
|
17936
18130
|
filteredEmpty.hidden = true;
|
|
@@ -18119,8 +18313,23 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
18119
18313
|
}
|
|
18120
18314
|
}
|
|
18121
18315
|
}
|
|
18316
|
+
function defaultColWidth(colName) {
|
|
18317
|
+
const type = (columns.find((c2) => c2.name === colName)?.type ?? "").toLowerCase();
|
|
18318
|
+
let w = DEFAULT_COL_WIDTH;
|
|
18319
|
+
if (/timestamp|datetime/.test(type))
|
|
18320
|
+
w = 210;
|
|
18321
|
+
else if (/^(date|time|year)/.test(type))
|
|
18322
|
+
w = 120;
|
|
18323
|
+
else if (/bool|tinyint\(1\)/.test(type))
|
|
18324
|
+
w = 80;
|
|
18325
|
+
else if (/int|decimal|numeric|float|double|real/.test(type))
|
|
18326
|
+
w = 110;
|
|
18327
|
+
else if (/text|json|xml|blob/.test(type))
|
|
18328
|
+
w = 260;
|
|
18329
|
+
return Math.max(w, Math.min(240, colName.length * 7.5 + 34));
|
|
18330
|
+
}
|
|
18122
18331
|
function getColWidth(colName) {
|
|
18123
|
-
return colWidths.get(colName) ??
|
|
18332
|
+
return colWidths.get(colName) ?? defaultColWidth(colName);
|
|
18124
18333
|
}
|
|
18125
18334
|
function applyColWidth(colName, index) {
|
|
18126
18335
|
const w = getColWidth(colName);
|
|
@@ -22417,7 +22626,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22417
22626
|
});
|
|
22418
22627
|
chip.addEventListener("dragend", () => clearDragState());
|
|
22419
22628
|
}
|
|
22420
|
-
|
|
22629
|
+
tabsBar.addEventListener("dragover", (e2) => {
|
|
22421
22630
|
if (!draggingTabId)
|
|
22422
22631
|
return;
|
|
22423
22632
|
const target = e2.target?.closest(".db-tabs-chip");
|
|
@@ -22428,7 +22637,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22428
22637
|
e2.dataTransfer.dropEffect = "move";
|
|
22429
22638
|
clearDropTarget();
|
|
22430
22639
|
});
|
|
22431
|
-
|
|
22640
|
+
tabsBar.addEventListener("drop", (e2) => {
|
|
22432
22641
|
if (!draggingTabId)
|
|
22433
22642
|
return;
|
|
22434
22643
|
const target = e2.target?.closest(".db-tabs-chip");
|
|
@@ -23072,7 +23281,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23072
23281
|
if (!el)
|
|
23073
23282
|
return;
|
|
23074
23283
|
el.hidden = !branch;
|
|
23075
|
-
|
|
23284
|
+
const name = el.querySelector(".project-branch-name");
|
|
23285
|
+
if (name)
|
|
23286
|
+
name.textContent = branch;
|
|
23076
23287
|
el.title = branch ? `Current branch: ${branch}` : "";
|
|
23077
23288
|
}
|
|
23078
23289
|
let metaFilesForViewedProgress = [];
|
|
@@ -23892,9 +24103,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23892
24103
|
const unfold = card.querySelector(".gdp-file-unfold");
|
|
23893
24104
|
if (unfold)
|
|
23894
24105
|
unfold.disabled = collapsed;
|
|
23895
|
-
|
|
23896
|
-
|
|
23897
|
-
|
|
24106
|
+
card.querySelectorAll(".gdp-preview-file, .gdp-view-file").forEach((button2) => {
|
|
24107
|
+
button2.disabled = collapsed;
|
|
24108
|
+
});
|
|
23898
24109
|
}
|
|
23899
24110
|
function setViewFileButtonState(button, sourceMode) {
|
|
23900
24111
|
if (!button)
|
|
@@ -24094,6 +24305,27 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
24094
24305
|
wrap.appendChild(box);
|
|
24095
24306
|
}
|
|
24096
24307
|
header.appendChild(wrap);
|
|
24308
|
+
if (!header.querySelector(".gdp-preview-file") && isPreviewableSource(fileSourceTarget(file).path)) {
|
|
24309
|
+
const previewFile = document.createElement("button");
|
|
24310
|
+
previewFile.type = "button";
|
|
24311
|
+
previewFile.className = "gdp-preview-file gdp-btn gdp-btn-sm";
|
|
24312
|
+
previewFile.textContent = "Preview";
|
|
24313
|
+
previewFile.title = "Preview rendered file";
|
|
24314
|
+
previewFile.addEventListener("click", (e2) => {
|
|
24315
|
+
e2.stopPropagation();
|
|
24316
|
+
const target = fileSourceTarget(file);
|
|
24317
|
+
setRoute({
|
|
24318
|
+
screen: "file",
|
|
24319
|
+
path: target.path,
|
|
24320
|
+
ref: target.ref,
|
|
24321
|
+
view: "blob",
|
|
24322
|
+
preview: true,
|
|
24323
|
+
range: currentRange()
|
|
24324
|
+
});
|
|
24325
|
+
applySourceRouteToShell();
|
|
24326
|
+
});
|
|
24327
|
+
header.appendChild(previewFile);
|
|
24328
|
+
}
|
|
24097
24329
|
if (!header.querySelector(".gdp-view-file")) {
|
|
24098
24330
|
const viewFile = document.createElement("button");
|
|
24099
24331
|
viewFile.type = "button";
|
|
@@ -26070,7 +26302,11 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26070
26302
|
},
|
|
26071
26303
|
{
|
|
26072
26304
|
kind: "paragraph",
|
|
26073
|
-
text: "A file detail page exposes up to four tabs — Preview, Code, Blame, History. For text files Code is the default and ?preview=1 opts in to the Markdown / HTML preview; media files (images, video, audio, PDF) show a Preview tab only, with no Code tab. Blame and History have their own canonical URLs (view=blame, view=history) so deep links and the browser back/forward stay in sync, and they keep the Repository sidebar visible."
|
|
26305
|
+
text: "A file detail page exposes up to four tabs — Preview, Code, Blame, History. For text files Code is the default and ?preview=1 opts in to the Markdown / HTML preview; media files (images, video, audio, PDF) show a Preview tab only, with no Code tab. Blame and History have their own canonical URLs (view=blame, view=history) so deep links and the browser back/forward stay in sync, and they keep the Repository sidebar visible. Opening another file from the repository tree keeps the active tab (a file that cannot be previewed falls back to Code)."
|
|
26306
|
+
},
|
|
26307
|
+
{
|
|
26308
|
+
kind: "paragraph",
|
|
26309
|
+
text: "When the repository remote is on GitHub, repository and file headers can open the current path there. Selecting source lines also exposes separate actions to copy the AI reference, open the exact GitHub line range, or copy its URL. Markdown and HTML diff cards include a direct Preview shortcut."
|
|
26074
26310
|
},
|
|
26075
26311
|
{
|
|
26076
26312
|
kind: "paragraph",
|
|
@@ -26163,6 +26399,10 @@ code-viewer doctor --bin git=/opt/bin/git --bin docker=/opt/bin/docker --bin gh=
|
|
|
26163
26399
|
kind: "paragraph",
|
|
26164
26400
|
text: "Everything in .code-viewer/ is owned by code-viewer. JSON files are rewritten safely with validation on every change, so unknown keys are dropped and invalid values are reset to defaults. Hand-edit at your own risk — a corrupt file is renamed with a .corrupt suffix and replaced with an empty default."
|
|
26165
26401
|
},
|
|
26402
|
+
{
|
|
26403
|
+
kind: "paragraph",
|
|
26404
|
+
text: "The directory appears in the repository tree and its text files can be inspected in the Code view. It remains excluded from repository searches and diffs."
|
|
26405
|
+
},
|
|
26166
26406
|
{
|
|
26167
26407
|
kind: "paragraph",
|
|
26168
26408
|
text: "Deleting the whole directory is the supported way to reset all per-repository state. Removing a single file resets only that subsystem (for example, deleting tabs.json closes all DB tabs on the next load)."
|
|
@@ -26271,6 +26511,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
26271
26511
|
[
|
|
26272
26512
|
"Persistent state",
|
|
26273
26513
|
"Open/closed, width, follow, mute, and rate are stored under .code-viewer/settings.json; annotations themselves live in .code-viewer/annotations.json."
|
|
26514
|
+
],
|
|
26515
|
+
[
|
|
26516
|
+
"Restorable URL",
|
|
26517
|
+
"The panel-open state, selected session, and selected annotation are kept in the URL, so reloads and shared links restore the same walkthrough context."
|
|
26274
26518
|
]
|
|
26275
26519
|
]
|
|
26276
26520
|
}
|
|
@@ -26741,7 +26985,11 @@ code-viewer query agent-help`
|
|
|
26741
26985
|
},
|
|
26742
26986
|
{
|
|
26743
26987
|
kind: "paragraph",
|
|
26744
|
-
text: "ファイル詳細ページには最大 4 つのタブ (Preview / Code / Blame / History) があります。テキストファイルは Code がデフォルトで、?preview=1 を付けると Markdown / HTML プレビューに切り替わります。画像・動画・音声・PDF などのメディアファイルは Preview タブのみ表示され、Code タブは表示されません。Blame と History はそれぞれ専用 URL (view=blame, view=history) を持つため、ディープリンクとブラウザの戻る / 進むが同期し、いずれも Repository
|
|
26988
|
+
text: "ファイル詳細ページには最大 4 つのタブ (Preview / Code / Blame / History) があります。テキストファイルは Code がデフォルトで、?preview=1 を付けると Markdown / HTML プレビューに切り替わります。画像・動画・音声・PDF などのメディアファイルは Preview タブのみ表示され、Code タブは表示されません。Blame と History はそれぞれ専用 URL (view=blame, view=history) を持つため、ディープリンクとブラウザの戻る / 進むが同期し、いずれも Repository サイドバーは表示されたままです。ツリーから別のファイルを開いても選択中のタブは維持されます (プレビューできないファイルでは Code に戻ります)。"
|
|
26989
|
+
},
|
|
26990
|
+
{
|
|
26991
|
+
kind: "paragraph",
|
|
26992
|
+
text: "リポジトリの remote が GitHub の場合、リポジトリとファイルのヘッダーから現在のパスを GitHub で開けます。ソース行を選択すると、AI 参照のコピー、選択行範囲を GitHub で開く、GitHub URL のコピーを個別に選べます。Markdown / HTML の diff カードには直接 Preview を開く導線も表示されます。"
|
|
26745
26993
|
},
|
|
26746
26994
|
{
|
|
26747
26995
|
kind: "paragraph",
|
|
@@ -26834,6 +27082,10 @@ code-viewer doctor --bin git=/opt/bin/git --bin docker=/opt/bin/docker --bin gh=
|
|
|
26834
27082
|
kind: "paragraph",
|
|
26835
27083
|
text: ".code-viewer/ の中身はすべて code-viewer が管理します。JSON ファイルは書き込みごとにバリデーションを通して安全に書き換えられるため、未知のキーは破棄され、不正な値は既定値に戻されます。手で編集すると壊れる可能性があり、壊れたファイルは .corrupt サフィックスに改名されて空の既定値で置き換えられます。"
|
|
26836
27084
|
},
|
|
27085
|
+
{
|
|
27086
|
+
kind: "paragraph",
|
|
27087
|
+
text: "ディレクトリはリポジトリツリーに表示され、テキストファイルは Code ビューで確認できます。リポジトリ検索と diff の対象からは引き続き除外されます。"
|
|
27088
|
+
},
|
|
26837
27089
|
{
|
|
26838
27090
|
kind: "paragraph",
|
|
26839
27091
|
text: "ディレクトリごと削除するのが、このリポジトリの全状態をリセットする推奨手順です。個別ファイルだけを消した場合はその系統だけがリセットされます(例: tabs.json を消すと次回起動時に DB タブがすべて閉じた状態になります)。"
|
|
@@ -26942,6 +27194,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
26942
27194
|
[
|
|
26943
27195
|
"永続化",
|
|
26944
27196
|
"パネルの開閉・幅・follow・ミュート・速度は .code-viewer/settings.json に、注釈自体は .code-viewer/annotations.json に保存されます。"
|
|
27197
|
+
],
|
|
27198
|
+
[
|
|
27199
|
+
"復元できる URL",
|
|
27200
|
+
"パネルの開閉、選択中のセッション、選択中の注釈は URL に反映されるため、リロードや共有リンクでも同じウォークスルー状態を復元できます。"
|
|
26945
27201
|
]
|
|
26946
27202
|
]
|
|
26947
27203
|
}
|
|
@@ -28224,7 +28480,7 @@ code-viewer query agent-help`
|
|
|
28224
28480
|
let mounted = false;
|
|
28225
28481
|
let lifecycle = 0;
|
|
28226
28482
|
let data = null;
|
|
28227
|
-
let activeTab = "
|
|
28483
|
+
let activeTab = "tasks";
|
|
28228
28484
|
let selectedDate = todayIsoDate();
|
|
28229
28485
|
let selectedEntryId = "";
|
|
28230
28486
|
let creatingEntry = false;
|
|
@@ -28397,7 +28653,7 @@ code-viewer query agent-help`
|
|
|
28397
28653
|
function applyRoute(route = deps.getRoute()) {
|
|
28398
28654
|
if (!isJournalRoute(route))
|
|
28399
28655
|
return;
|
|
28400
|
-
activeTab = route.tab || activeTab || "
|
|
28656
|
+
activeTab = route.tab || activeTab || "tasks";
|
|
28401
28657
|
selectedDate = route.date || selectedDate || todayIsoDate();
|
|
28402
28658
|
labelFilter = route.label || "";
|
|
28403
28659
|
selectedTaskId = route.task || "";
|
|
@@ -29960,21 +30216,50 @@ code-viewer query agent-help`
|
|
|
29960
30216
|
const copyButton = document.createElement("button");
|
|
29961
30217
|
copyButton.id = "line-ref-pill-copy";
|
|
29962
30218
|
copyButton.type = "button";
|
|
29963
|
-
copyButton.title = "選択行の参照をコピー(Claude Code / Codex に貼り付け用)。Shift+Click でコード本体も添付。";
|
|
29964
30219
|
const closeButton = document.createElement("button");
|
|
29965
30220
|
closeButton.id = "line-ref-pill-close";
|
|
29966
30221
|
closeButton.type = "button";
|
|
29967
30222
|
closeButton.title = "選択を解除";
|
|
29968
30223
|
closeButton.setAttribute("aria-label", "選択を解除");
|
|
29969
30224
|
closeButton.textContent = "×";
|
|
29970
|
-
|
|
29971
|
-
pill
|
|
30225
|
+
const githubActions = document.createElement("div");
|
|
30226
|
+
githubActions.id = "line-ref-pill-github-actions";
|
|
30227
|
+
githubActions.hidden = true;
|
|
30228
|
+
const githubOpen = document.createElement("a");
|
|
30229
|
+
githubOpen.id = "line-ref-pill-github-open";
|
|
30230
|
+
githubOpen.target = "_blank";
|
|
30231
|
+
githubOpen.rel = "noopener";
|
|
30232
|
+
githubOpen.innerHTML = iconSvg("octicon-mark-github", MARK_GITHUB_16_PATH) + '<span class="lrp-github-open-label"></span>' + iconSvg("octicon-link-external", OPEN_EXTERNAL_16_PATH);
|
|
30233
|
+
const githubCopy = document.createElement("button");
|
|
30234
|
+
githubCopy.id = "line-ref-pill-github-copy";
|
|
30235
|
+
githubCopy.type = "button";
|
|
30236
|
+
githubCopy.innerHTML = `<span class="lrp-github-copy-icon">${iconSvg("octicon-copy", COPY_16_PATHS)}</span>` + '<span class="lrp-github-copy-label"></span>';
|
|
30237
|
+
githubActions.append(githubOpen, githubCopy);
|
|
30238
|
+
pill.append(copyButton, githubActions, closeButton);
|
|
29972
30239
|
document.body.appendChild(pill);
|
|
29973
30240
|
let refText = "";
|
|
29974
30241
|
let currentPath = "";
|
|
29975
30242
|
let currentStart = 0;
|
|
29976
30243
|
let currentEnd = 0;
|
|
30244
|
+
let githubUrl = "";
|
|
29977
30245
|
let feedbackTimer = null;
|
|
30246
|
+
let githubFeedbackTimer = null;
|
|
30247
|
+
function renderGithubActions() {
|
|
30248
|
+
const openTitle = deps.githubOpenTitle();
|
|
30249
|
+
const copyTitle = deps.githubCopyTitle();
|
|
30250
|
+
githubOpen.title = openTitle;
|
|
30251
|
+
githubOpen.setAttribute("aria-label", openTitle);
|
|
30252
|
+
githubCopy.title = copyTitle;
|
|
30253
|
+
githubCopy.setAttribute("aria-label", copyTitle);
|
|
30254
|
+
const openLabel = githubOpen.querySelector(".lrp-github-open-label");
|
|
30255
|
+
if (openLabel)
|
|
30256
|
+
openLabel.textContent = openTitle;
|
|
30257
|
+
const copyLabel = githubCopy.querySelector(".lrp-github-copy-label");
|
|
30258
|
+
if (copyLabel)
|
|
30259
|
+
copyLabel.textContent = copyTitle;
|
|
30260
|
+
githubOpen.href = githubUrl || "#";
|
|
30261
|
+
githubActions.hidden = !githubUrl;
|
|
30262
|
+
}
|
|
29978
30263
|
function selectionLineCount() {
|
|
29979
30264
|
return currentEnd - currentStart + 1;
|
|
29980
30265
|
}
|
|
@@ -29983,25 +30268,16 @@ code-viewer query agent-help`
|
|
|
29983
30268
|
if (count <= 1)
|
|
29984
30269
|
return "";
|
|
29985
30270
|
const warn = count >= AI_CONTEXT_LARGE_SELECTION_LINE_THRESHOLD;
|
|
29986
|
-
return `<span class="lrp-count${warn ? " lrp-count-warn" : ""}">${count}
|
|
30271
|
+
return `<span class="lrp-count${warn ? " lrp-count-warn" : ""}">${escapeHtml2(deps.lineCountLabel(count))}</span>`;
|
|
29987
30272
|
}
|
|
29988
30273
|
function render(state) {
|
|
29989
|
-
|
|
29990
|
-
|
|
29991
|
-
|
|
29992
|
-
|
|
29993
|
-
}
|
|
29994
|
-
|
|
29995
|
-
|
|
29996
|
-
const suffix = count > 1 ? ` (${count} lines)` : "";
|
|
29997
|
-
copyButton.innerHTML = `${CHECK_ICON}<span class="lrp-label">Copied + code${suffix}</span>`;
|
|
29998
|
-
return;
|
|
29999
|
-
}
|
|
30000
|
-
if (state === "failed") {
|
|
30001
|
-
copyButton.innerHTML = `${COPY_ICON}<span class="lrp-label">copy failed</span>`;
|
|
30002
|
-
return;
|
|
30003
|
-
}
|
|
30004
|
-
copyButton.innerHTML = `${COPY_ICON}<span class="lrp-label">Copy</span>` + `<span class="lrp-ref">${escapeHtml2(refText)}</span>` + countBadgeHtml();
|
|
30274
|
+
copyButton.classList.toggle("copied", state === "copied" || state === "copied-code");
|
|
30275
|
+
copyButton.classList.toggle("failed", state === "failed");
|
|
30276
|
+
const icon = state === "copied" || state === "copied-code" ? CHECK_ICON : COPY_ICON;
|
|
30277
|
+
const label = deps.copyReferenceLabel();
|
|
30278
|
+
copyButton.innerHTML = `${icon}<span class="lrp-label">${escapeHtml2(label)}</span>` + `<span class="lrp-ref">${escapeHtml2(refText)}</span>` + countBadgeHtml();
|
|
30279
|
+
copyButton.title = label;
|
|
30280
|
+
copyButton.setAttribute("aria-label", label);
|
|
30005
30281
|
}
|
|
30006
30282
|
copyButton.addEventListener("click", async (event) => {
|
|
30007
30283
|
if (!refText)
|
|
@@ -30030,6 +30306,28 @@ code-viewer query agent-help`
|
|
|
30030
30306
|
render("ready");
|
|
30031
30307
|
}, 1200);
|
|
30032
30308
|
});
|
|
30309
|
+
githubCopy.addEventListener("click", async () => {
|
|
30310
|
+
if (!githubUrl)
|
|
30311
|
+
return;
|
|
30312
|
+
try {
|
|
30313
|
+
await navigator.clipboard.writeText(githubUrl);
|
|
30314
|
+
githubCopy.classList.add("copied");
|
|
30315
|
+
const icon = githubCopy.querySelector(".lrp-github-copy-icon");
|
|
30316
|
+
if (icon)
|
|
30317
|
+
icon.innerHTML = CHECK_ICON;
|
|
30318
|
+
} catch {
|
|
30319
|
+
githubCopy.classList.add("failed");
|
|
30320
|
+
}
|
|
30321
|
+
if (githubFeedbackTimer)
|
|
30322
|
+
clearTimeout(githubFeedbackTimer);
|
|
30323
|
+
githubFeedbackTimer = setTimeout(() => {
|
|
30324
|
+
githubFeedbackTimer = null;
|
|
30325
|
+
githubCopy.classList.remove("copied", "failed");
|
|
30326
|
+
const icon = githubCopy.querySelector(".lrp-github-copy-icon");
|
|
30327
|
+
if (icon)
|
|
30328
|
+
icon.innerHTML = iconSvg("octicon-copy", COPY_16_PATHS);
|
|
30329
|
+
}, 1200);
|
|
30330
|
+
});
|
|
30033
30331
|
closeButton.addEventListener("click", () => {
|
|
30034
30332
|
deps.onClose();
|
|
30035
30333
|
});
|
|
@@ -30043,6 +30341,8 @@ code-viewer query agent-help`
|
|
|
30043
30341
|
currentPath = path;
|
|
30044
30342
|
currentStart = Math.max(1, Math.floor(Math.min(start, end)));
|
|
30045
30343
|
currentEnd = Math.max(1, Math.floor(Math.max(start, end)));
|
|
30344
|
+
githubUrl = deps.githubUrlForSelection(currentPath, currentStart, currentEnd) || "";
|
|
30345
|
+
renderGithubActions();
|
|
30046
30346
|
if (feedbackTimer) {
|
|
30047
30347
|
clearTimeout(feedbackTimer);
|
|
30048
30348
|
feedbackTimer = null;
|
|
@@ -30060,6 +30360,8 @@ code-viewer query agent-help`
|
|
|
30060
30360
|
currentPath = "";
|
|
30061
30361
|
currentStart = 0;
|
|
30062
30362
|
currentEnd = 0;
|
|
30363
|
+
githubUrl = "";
|
|
30364
|
+
githubActions.hidden = true;
|
|
30063
30365
|
pill.hidden = true;
|
|
30064
30366
|
}
|
|
30065
30367
|
};
|
|
@@ -30529,6 +30831,19 @@ code-viewer query agent-help`
|
|
|
30529
30831
|
return trimmed;
|
|
30530
30832
|
}
|
|
30531
30833
|
|
|
30834
|
+
// web-src/views/repository-web-link.ts
|
|
30835
|
+
function createRepositoryWebLink(target, label) {
|
|
30836
|
+
const link2 = document.createElement("a");
|
|
30837
|
+
link2.className = "gdp-btn gdp-btn-sm gdp-repo-web-link";
|
|
30838
|
+
link2.href = target.url;
|
|
30839
|
+
link2.target = "_blank";
|
|
30840
|
+
link2.rel = "noopener";
|
|
30841
|
+
link2.title = label;
|
|
30842
|
+
link2.setAttribute("aria-label", label);
|
|
30843
|
+
link2.innerHTML = `${iconSvg(target.provider === "github" ? "octicon-mark-github" : "octicon-link-external", target.provider === "github" ? MARK_GITHUB_16_PATH : OPEN_EXTERNAL_16_PATH)}<span>${label}</span>`;
|
|
30844
|
+
return link2;
|
|
30845
|
+
}
|
|
30846
|
+
|
|
30532
30847
|
// web-src/core/file-filter.ts
|
|
30533
30848
|
function normalizeFileFilterQuery(value) {
|
|
30534
30849
|
return (value || "").toLowerCase().trim();
|
|
@@ -32240,6 +32555,9 @@ code-viewer query agent-help`
|
|
|
32240
32555
|
repositoryFallback,
|
|
32241
32556
|
repositoryRootFallback,
|
|
32242
32557
|
commitEntryMeta,
|
|
32558
|
+
repositoryWebTarget,
|
|
32559
|
+
openGithubLabel,
|
|
32560
|
+
openRepositoryWebLabel,
|
|
32243
32561
|
fileBadge
|
|
32244
32562
|
} = deps;
|
|
32245
32563
|
let REPO_SORT = {
|
|
@@ -32395,6 +32713,13 @@ code-viewer query agent-help`
|
|
|
32395
32713
|
});
|
|
32396
32714
|
return button;
|
|
32397
32715
|
}
|
|
32716
|
+
function createRepositoryWebLink2(path, ref) {
|
|
32717
|
+
const target = repositoryWebTarget(path, ref);
|
|
32718
|
+
if (!target)
|
|
32719
|
+
return null;
|
|
32720
|
+
const label = target.provider === "github" ? openGithubLabel() : openRepositoryWebLabel();
|
|
32721
|
+
return createRepositoryWebLink(target, label);
|
|
32722
|
+
}
|
|
32398
32723
|
function showRepoContextMenu(event, entry, ref, onChanged) {
|
|
32399
32724
|
if (document.querySelector(".gdp-dialog-backdrop"))
|
|
32400
32725
|
return false;
|
|
@@ -32632,6 +32957,9 @@ code-viewer query agent-help`
|
|
|
32632
32957
|
pathHeader.appendChild(createCopyPathButton(meta.path));
|
|
32633
32958
|
pathHeader.appendChild(createOpenPathButton(meta.path || "", "directory", openDirectoryInOsTitle()));
|
|
32634
32959
|
toolbar.appendChild(pathHeader);
|
|
32960
|
+
const repositoryWebLink = createRepositoryWebLink2(meta.path || "", meta.ref);
|
|
32961
|
+
if (repositoryWebLink)
|
|
32962
|
+
toolbar.appendChild(repositoryWebLink);
|
|
32635
32963
|
if (canTrashWorktreeRef(meta.ref)) {
|
|
32636
32964
|
toolbar.appendChild(createNewFolderButton(meta.path || "", () => loadRepo()));
|
|
32637
32965
|
if (meta.path) {
|
|
@@ -32844,14 +33172,10 @@ code-viewer query agent-help`
|
|
|
32844
33172
|
loadRepo();
|
|
32845
33173
|
return;
|
|
32846
33174
|
}
|
|
32847
|
-
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
ref: normalizedRef
|
|
32851
|
-
view: "blob",
|
|
32852
|
-
range: currentRange()
|
|
32853
|
-
});
|
|
32854
|
-
renderStandaloneSource({ path: file.path, ref: normalizedRef });
|
|
33175
|
+
const fileRoute = fileRouteKeepingActiveView(STATE.route, { path: file.path, ref: normalizedRef }, currentRange());
|
|
33176
|
+
setRoute(fileRoute);
|
|
33177
|
+
if (fileRoute.view === "blob")
|
|
33178
|
+
renderStandaloneSource({ path: file.path, ref: normalizedRef });
|
|
32855
33179
|
});
|
|
32856
33180
|
await activateRepoSidebarPath(currentPath);
|
|
32857
33181
|
}).catch(() => {
|
|
@@ -33985,6 +34309,7 @@ code-viewer query agent-help`
|
|
|
33985
34309
|
renderRepoBlobSidebar,
|
|
33986
34310
|
placeSidebarToggle,
|
|
33987
34311
|
createFileBreadcrumb,
|
|
34312
|
+
createRepositoryWebLink: createRepositoryWebLink2,
|
|
33988
34313
|
createFileDetailMeta,
|
|
33989
34314
|
createOpenPathButton,
|
|
33990
34315
|
createMoveToTrashButton,
|
|
@@ -34003,7 +34328,6 @@ code-viewer query agent-help`
|
|
|
34003
34328
|
const VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH = 2000;
|
|
34004
34329
|
const UNKNOWN_TEXT_SNIFF_BYTES = 8192;
|
|
34005
34330
|
const SOURCE_LOADING_SLOW_THRESHOLD_MS = 3000;
|
|
34006
|
-
let sourceShikiLoadPromise = null;
|
|
34007
34331
|
let PREFERRED_SOURCE_TAB = null;
|
|
34008
34332
|
let SOURCE_CURSOR = null;
|
|
34009
34333
|
let SOURCE_CURSOR_ROWS = [];
|
|
@@ -34016,8 +34340,13 @@ code-viewer query agent-help`
|
|
|
34016
34340
|
if (sourceRow)
|
|
34017
34341
|
return sourceRow.getBoundingClientRect().height || 20;
|
|
34018
34342
|
const preview = document.querySelector("#content .gdp-markdown-preview:not([hidden])");
|
|
34019
|
-
|
|
34020
|
-
|
|
34343
|
+
if (preview) {
|
|
34344
|
+
const previewLineHeight = Number.parseFloat(getComputedStyle(preview).lineHeight);
|
|
34345
|
+
if (Number.isFinite(previewLineHeight) && previewLineHeight > 0)
|
|
34346
|
+
return previewLineHeight;
|
|
34347
|
+
}
|
|
34348
|
+
const configuredLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
34349
|
+
return Number.isFinite(configuredLineHeight) && configuredLineHeight > 0 ? configuredLineHeight : VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
34021
34350
|
}
|
|
34022
34351
|
function hasVisibleSourceCodeSurface() {
|
|
34023
34352
|
return Array.from(document.querySelectorAll("#content .gdp-source-virtual-scroller, #content .gdp-source-table")).some((item) => item.offsetParent !== null);
|
|
@@ -34058,8 +34387,9 @@ code-viewer query agent-help`
|
|
|
34058
34387
|
}
|
|
34059
34388
|
function visibleSourceLineFallback() {
|
|
34060
34389
|
const scroller = findMainScrollTarget();
|
|
34390
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
34061
34391
|
if (scroller)
|
|
34062
|
-
return Math.max(1, Math.floor(scroller.scrollTop /
|
|
34392
|
+
return Math.max(1, Math.floor(scroller.scrollTop / rowHeight) + 1);
|
|
34063
34393
|
const rows = $$("#content .gdp-source-table tr[data-line]");
|
|
34064
34394
|
const contentTop = document.querySelector("#content")?.getBoundingClientRect().top ?? 0;
|
|
34065
34395
|
const row = rows.find((item) => item.getBoundingClientRect().bottom >= Math.max(0, contentTop));
|
|
@@ -34083,8 +34413,9 @@ code-viewer query agent-help`
|
|
|
34083
34413
|
function scrollSourceCursorIntoView(cursor, edge = "nearest") {
|
|
34084
34414
|
const scroller = findMainScrollTarget();
|
|
34085
34415
|
if (scroller) {
|
|
34086
|
-
const
|
|
34087
|
-
const
|
|
34416
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
34417
|
+
const top = (cursor.line - 1) * rowHeight;
|
|
34418
|
+
const bottom = top + rowHeight;
|
|
34088
34419
|
const before = scroller.scrollTop;
|
|
34089
34420
|
if (edge === "center")
|
|
34090
34421
|
scroller.scrollTop = Math.max(0, top - Math.round(scroller.clientHeight / 2));
|
|
@@ -34177,86 +34508,13 @@ code-viewer query agent-help`
|
|
|
34177
34508
|
focusMainPanel();
|
|
34178
34509
|
return true;
|
|
34179
34510
|
}
|
|
34180
|
-
|
|
34181
|
-
|
|
34182
|
-
|
|
34183
|
-
|
|
34184
|
-
|
|
34185
|
-
|
|
34186
|
-
|
|
34187
|
-
"cmake",
|
|
34188
|
-
"cpp",
|
|
34189
|
-
"csharp",
|
|
34190
|
-
"css",
|
|
34191
|
-
"dart",
|
|
34192
|
-
"diff",
|
|
34193
|
-
"dockerfile",
|
|
34194
|
-
"dotenv",
|
|
34195
|
-
"elixir",
|
|
34196
|
-
"erb",
|
|
34197
|
-
"erlang",
|
|
34198
|
-
"fortran",
|
|
34199
|
-
"go",
|
|
34200
|
-
"gradle",
|
|
34201
|
-
"graphql",
|
|
34202
|
-
"haml",
|
|
34203
|
-
"handlebars",
|
|
34204
|
-
"haskell",
|
|
34205
|
-
"html",
|
|
34206
|
-
"ini",
|
|
34207
|
-
"java",
|
|
34208
|
-
"javascript",
|
|
34209
|
-
"json",
|
|
34210
|
-
"jsonc",
|
|
34211
|
-
"julia",
|
|
34212
|
-
"kotlin",
|
|
34213
|
-
"less",
|
|
34214
|
-
"liquid",
|
|
34215
|
-
"lua",
|
|
34216
|
-
"make",
|
|
34217
|
-
"markdown",
|
|
34218
|
-
"nix",
|
|
34219
|
-
"ocaml",
|
|
34220
|
-
"pascal",
|
|
34221
|
-
"perl",
|
|
34222
|
-
"php",
|
|
34223
|
-
"powershell",
|
|
34224
|
-
"prisma",
|
|
34225
|
-
"properties",
|
|
34226
|
-
"protobuf",
|
|
34227
|
-
"pug",
|
|
34228
|
-
"python",
|
|
34229
|
-
"r",
|
|
34230
|
-
"rst",
|
|
34231
|
-
"ruby",
|
|
34232
|
-
"rust",
|
|
34233
|
-
"sass",
|
|
34234
|
-
"scala",
|
|
34235
|
-
"scss",
|
|
34236
|
-
"sql",
|
|
34237
|
-
"swift",
|
|
34238
|
-
"terraform",
|
|
34239
|
-
"tex",
|
|
34240
|
-
"toml",
|
|
34241
|
-
"twig",
|
|
34242
|
-
"typescript",
|
|
34243
|
-
"vim",
|
|
34244
|
-
"vue",
|
|
34245
|
-
"xml",
|
|
34246
|
-
"yaml"
|
|
34247
|
-
]));
|
|
34248
|
-
function loadSourceShikiHighlighter() {
|
|
34249
|
-
if (!sourceShikiLoadPromise) {
|
|
34250
|
-
sourceShikiLoadPromise = import("/shiki.js").then((mod) => {
|
|
34251
|
-
const typed = mod;
|
|
34252
|
-
const langs = typed.bundledLanguages ? SOURCE_SHIKI_LANGS.filter((lang) => !!typed.bundledLanguages?.[lang]) : SOURCE_SHIKI_LANGS;
|
|
34253
|
-
return typed.createHighlighter({
|
|
34254
|
-
themes: ["github-light", "github-dark"],
|
|
34255
|
-
langs
|
|
34256
|
-
});
|
|
34257
|
-
}).catch(() => null);
|
|
34258
|
-
}
|
|
34259
|
-
return sourceShikiLoadPromise;
|
|
34511
|
+
function loadSourceShikiHighlighter(lang) {
|
|
34512
|
+
if (deps.loadSourceHighlighter)
|
|
34513
|
+
return deps.loadSourceHighlighter(lang);
|
|
34514
|
+
return loadShikiHighlighter({
|
|
34515
|
+
themes: ["github-light", "github-dark"],
|
|
34516
|
+
langs: [lang]
|
|
34517
|
+
});
|
|
34260
34518
|
}
|
|
34261
34519
|
function sourceShikiLines(textValue, lang, highlighter) {
|
|
34262
34520
|
try {
|
|
@@ -34275,6 +34533,57 @@ code-viewer query agent-help`
|
|
|
34275
34533
|
return null;
|
|
34276
34534
|
}
|
|
34277
34535
|
}
|
|
34536
|
+
function scheduleSourceHighlight(table2, target, textValue, lang, signal) {
|
|
34537
|
+
setTimeout(() => {
|
|
34538
|
+
if (signal?.aborted || !table2.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34539
|
+
return;
|
|
34540
|
+
loadSourceShikiHighlighter(lang).then((highlighter) => {
|
|
34541
|
+
if (!highlighter || signal?.aborted || !table2.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34542
|
+
return;
|
|
34543
|
+
const highlightedLines = sourceShikiLines(textValue, lang, highlighter);
|
|
34544
|
+
if (!highlightedLines || signal?.aborted || !table2.isConnected || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34545
|
+
return;
|
|
34546
|
+
const cells = table2.querySelectorAll(".gdp-source-line-code");
|
|
34547
|
+
cells.forEach((cell, index) => {
|
|
34548
|
+
if (highlightedLines[index] == null)
|
|
34549
|
+
return;
|
|
34550
|
+
cell.innerHTML = highlightedLines[index] || " ";
|
|
34551
|
+
cell.classList.add("shiki");
|
|
34552
|
+
});
|
|
34553
|
+
}).catch((err) => {
|
|
34554
|
+
console.error("Failed to apply source syntax highlighting", err);
|
|
34555
|
+
});
|
|
34556
|
+
}, 0);
|
|
34557
|
+
}
|
|
34558
|
+
function scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, onReplace) {
|
|
34559
|
+
setTimeout(() => {
|
|
34560
|
+
if (signal?.aborted || !preview.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34561
|
+
return;
|
|
34562
|
+
(deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34563
|
+
syntaxHighlight: true,
|
|
34564
|
+
signal,
|
|
34565
|
+
onNavigateMarkdown: (path, ref) => {
|
|
34566
|
+
setRoute({
|
|
34567
|
+
screen: "file",
|
|
34568
|
+
path,
|
|
34569
|
+
ref,
|
|
34570
|
+
view: "blob",
|
|
34571
|
+
range: currentRange()
|
|
34572
|
+
});
|
|
34573
|
+
renderStandaloneSource({ path, ref });
|
|
34574
|
+
}
|
|
34575
|
+
}).then((next) => {
|
|
34576
|
+
if (signal?.aborted || !preview.isConnected || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34577
|
+
return;
|
|
34578
|
+
next.dataset.sourcePane = "preview";
|
|
34579
|
+
next.hidden = preview.hidden;
|
|
34580
|
+
preview.replaceWith(next);
|
|
34581
|
+
onReplace(next);
|
|
34582
|
+
}).catch((err) => {
|
|
34583
|
+
console.error("Failed to apply preview syntax highlighting", err);
|
|
34584
|
+
});
|
|
34585
|
+
}, 0);
|
|
34586
|
+
}
|
|
34278
34587
|
function setPreferredSourceTab(tab) {
|
|
34279
34588
|
PREFERRED_SOURCE_TAB = tab;
|
|
34280
34589
|
}
|
|
@@ -34438,24 +34747,14 @@ code-viewer query agent-help`
|
|
|
34438
34747
|
card.appendChild(view);
|
|
34439
34748
|
setSourceCardState(card, "done");
|
|
34440
34749
|
}
|
|
34441
|
-
function renderSourceInternalPath(card, target
|
|
34750
|
+
function renderSourceInternalPath(card, target) {
|
|
34442
34751
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
34443
34752
|
const info = createSourceFileInfo(target, "internal metadata", {
|
|
34444
34753
|
loadMeta: false
|
|
34445
34754
|
});
|
|
34446
|
-
const extraChildren = [info];
|
|
34447
|
-
if (kind === "code-viewer") {
|
|
34448
|
-
const link2 = document.createElement("a");
|
|
34449
|
-
link2.className = "gdp-btn gdp-btn-sm gdp-source-download";
|
|
34450
|
-
link2.href = buildRawFileUrl(target);
|
|
34451
|
-
link2.textContent = "Download raw";
|
|
34452
|
-
link2.target = "_blank";
|
|
34453
|
-
link2.rel = "noreferrer";
|
|
34454
|
-
extraChildren.push(link2);
|
|
34455
|
-
}
|
|
34456
34755
|
const view = renderUnsupportedPreview({
|
|
34457
|
-
message:
|
|
34458
|
-
extraChildren
|
|
34756
|
+
message: "Git internal metadata is not previewed from the file viewer.",
|
|
34757
|
+
extraChildren: [info]
|
|
34459
34758
|
});
|
|
34460
34759
|
if (body)
|
|
34461
34760
|
body.replaceWith(view);
|
|
@@ -34512,7 +34811,7 @@ code-viewer query agent-help`
|
|
|
34512
34811
|
const tabs = document.createElement("div");
|
|
34513
34812
|
tabs.className = "gdp-source-tabs";
|
|
34514
34813
|
const { codeButton, previewButton } = appendFileViewTabs(tabs, { currentRange, setRoute, setPreferredSourceTab }, target, active, {
|
|
34515
|
-
includeFileTabs: STATE.route.screen === "file",
|
|
34814
|
+
includeFileTabs: STATE.route.screen === "file" && sourceInternalPathKind(target.path) !== "code-viewer",
|
|
34516
34815
|
previewable: !!options.previewable || active === "preview",
|
|
34517
34816
|
sourceTabClick: "manual",
|
|
34518
34817
|
...textValue != null ? { sourceCopyButton: createSourceCopyButton(textValue) } : {}
|
|
@@ -34536,9 +34835,9 @@ code-viewer query agent-help`
|
|
|
34536
34835
|
header.textContent = `${target.path} @ ${target.ref}`;
|
|
34537
34836
|
}
|
|
34538
34837
|
const lang = inferLang(target.path);
|
|
34838
|
+
const sourceShikiLang = normalizeSourceShikiLang(lang);
|
|
34539
34839
|
const usesVirtualSource = shouldVirtualizeSource(textValue, lines) && !isVirtualSourceDisabled();
|
|
34540
34840
|
const hljsRef = STATE.syntaxHighlight && usesVirtualSource ? await loadSyntaxHighlighter() : null;
|
|
34541
|
-
const sourceShikiRef = STATE.syntaxHighlight && !usesVirtualSource ? await loadSourceShikiHighlighter() : null;
|
|
34542
34841
|
if (signal?.aborted)
|
|
34543
34842
|
return false;
|
|
34544
34843
|
const previewable = isPreviewableSource(target.path);
|
|
@@ -34554,8 +34853,8 @@ code-viewer query agent-help`
|
|
|
34554
34853
|
tabsHost.hidden = false;
|
|
34555
34854
|
tabsHost.replaceChildren(tabs3);
|
|
34556
34855
|
}
|
|
34557
|
-
|
|
34558
|
-
syntaxHighlight:
|
|
34856
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34857
|
+
syntaxHighlight: false,
|
|
34559
34858
|
signal,
|
|
34560
34859
|
onNavigateMarkdown: (path, ref) => {
|
|
34561
34860
|
setRoute({
|
|
@@ -34571,9 +34870,19 @@ code-viewer query agent-help`
|
|
|
34571
34870
|
if (signal?.aborted)
|
|
34572
34871
|
return false;
|
|
34573
34872
|
preview.dataset.sourcePane = "preview";
|
|
34873
|
+
let previewHighlightScheduled = false;
|
|
34874
|
+
const ensurePreviewHighlight = () => {
|
|
34875
|
+
if (previewKind === "html" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
34876
|
+
return;
|
|
34877
|
+
previewHighlightScheduled = true;
|
|
34878
|
+
scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, (next) => {
|
|
34879
|
+
preview = next;
|
|
34880
|
+
});
|
|
34881
|
+
};
|
|
34574
34882
|
applyRenderedSourceTab(initialSourceTab, codeButton2, previewButton2, virtualCode, preview, false);
|
|
34575
34883
|
previewButton2?.addEventListener("click", () => {
|
|
34576
34884
|
applyRenderedSourceTab("preview", codeButton2, previewButton2, virtualCode, preview);
|
|
34885
|
+
ensurePreviewHighlight();
|
|
34577
34886
|
});
|
|
34578
34887
|
codeButton2?.addEventListener("click", () => {
|
|
34579
34888
|
applyRenderedSourceTab("code", codeButton2, previewButton2, virtualCode, preview);
|
|
@@ -34586,6 +34895,8 @@ code-viewer query agent-help`
|
|
|
34586
34895
|
body.replaceWith(view);
|
|
34587
34896
|
else
|
|
34588
34897
|
card.appendChild(view);
|
|
34898
|
+
if (initialSourceTab === "preview")
|
|
34899
|
+
ensurePreviewHighlight();
|
|
34589
34900
|
return true;
|
|
34590
34901
|
}
|
|
34591
34902
|
const { tabs: tabs2 } = createSourceTabs(target, "code", textValue, {
|
|
@@ -34611,8 +34922,6 @@ code-viewer query agent-help`
|
|
|
34611
34922
|
table2.className = "gdp-source-table";
|
|
34612
34923
|
table2.dataset.sourcePane = "code";
|
|
34613
34924
|
const tbody = document.createElement("tbody");
|
|
34614
|
-
const sourceShikiLang = normalizeSourceShikiLang(lang);
|
|
34615
|
-
const shikiLines = sourceShikiRef && sourceShikiLang ? sourceShikiLines(textValue, sourceShikiLang, sourceShikiRef) : null;
|
|
34616
34925
|
for (let index = 0;index < lines.length; index++) {
|
|
34617
34926
|
if (signal?.aborted)
|
|
34618
34927
|
return false;
|
|
@@ -34627,12 +34936,7 @@ code-viewer query agent-help`
|
|
|
34627
34936
|
bindSourceLineNumber(num, card, target, index + 1);
|
|
34628
34937
|
const code2 = document.createElement("td");
|
|
34629
34938
|
code2.className = "gdp-source-line-code";
|
|
34630
|
-
|
|
34631
|
-
code2.innerHTML = shikiLines[index] || " ";
|
|
34632
|
-
code2.classList.add("shiki");
|
|
34633
|
-
} else {
|
|
34634
|
-
code2.textContent = line || " ";
|
|
34635
|
-
}
|
|
34939
|
+
code2.textContent = line || " ";
|
|
34636
34940
|
tr.appendChild(num);
|
|
34637
34941
|
tr.appendChild(code2);
|
|
34638
34942
|
tbody.appendChild(tr);
|
|
@@ -34649,8 +34953,8 @@ code-viewer query agent-help`
|
|
|
34649
34953
|
tabsHost.replaceChildren(tabs);
|
|
34650
34954
|
}
|
|
34651
34955
|
if (previewable) {
|
|
34652
|
-
|
|
34653
|
-
syntaxHighlight:
|
|
34956
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34957
|
+
syntaxHighlight: false,
|
|
34654
34958
|
signal,
|
|
34655
34959
|
onNavigateMarkdown: (path, ref) => {
|
|
34656
34960
|
setRoute({
|
|
@@ -34666,9 +34970,19 @@ code-viewer query agent-help`
|
|
|
34666
34970
|
if (signal?.aborted)
|
|
34667
34971
|
return false;
|
|
34668
34972
|
preview.dataset.sourcePane = "preview";
|
|
34973
|
+
let previewHighlightScheduled = false;
|
|
34974
|
+
const ensurePreviewHighlight = () => {
|
|
34975
|
+
if (previewKind === "html" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
34976
|
+
return;
|
|
34977
|
+
previewHighlightScheduled = true;
|
|
34978
|
+
scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, (next) => {
|
|
34979
|
+
preview = next;
|
|
34980
|
+
});
|
|
34981
|
+
};
|
|
34669
34982
|
applyRenderedSourceTab(initialSourceTab, codeButton, previewButton, table2, preview, false);
|
|
34670
34983
|
previewButton?.addEventListener("click", () => {
|
|
34671
34984
|
applyRenderedSourceTab("preview", codeButton, previewButton, table2, preview);
|
|
34985
|
+
ensurePreviewHighlight();
|
|
34672
34986
|
});
|
|
34673
34987
|
codeButton?.addEventListener("click", () => {
|
|
34674
34988
|
applyRenderedSourceTab("code", codeButton, previewButton, table2, preview);
|
|
@@ -34683,6 +34997,10 @@ code-viewer query agent-help`
|
|
|
34683
34997
|
body.replaceWith(view);
|
|
34684
34998
|
else
|
|
34685
34999
|
card.appendChild(view);
|
|
35000
|
+
if (STATE.syntaxHighlight && sourceShikiLang)
|
|
35001
|
+
scheduleSourceHighlight(table2, target, textValue, sourceShikiLang, signal);
|
|
35002
|
+
if (initialSourceTab === "preview")
|
|
35003
|
+
ensurePreviewHighlight();
|
|
34686
35004
|
return true;
|
|
34687
35005
|
}
|
|
34688
35006
|
if (header)
|
|
@@ -34694,6 +35012,8 @@ code-viewer query agent-help`
|
|
|
34694
35012
|
body.replaceWith(view);
|
|
34695
35013
|
else
|
|
34696
35014
|
card.appendChild(view);
|
|
35015
|
+
if (STATE.syntaxHighlight && sourceShikiLang)
|
|
35016
|
+
scheduleSourceHighlight(table2, target, textValue, sourceShikiLang, signal);
|
|
34697
35017
|
return true;
|
|
34698
35018
|
}
|
|
34699
35019
|
function shouldVirtualizeSource(textValue, lines) {
|
|
@@ -34885,8 +35205,10 @@ code-viewer query agent-help`
|
|
|
34885
35205
|
matches = nextMatches;
|
|
34886
35206
|
active = matches.length ? Math.max(0, Math.min(active, matches.length - 1)) : -1;
|
|
34887
35207
|
count.textContent = matches.length ? `${active + 1} / ${matches.length}` : "0 / 0";
|
|
34888
|
-
if (active >= 0)
|
|
34889
|
-
|
|
35208
|
+
if (active >= 0) {
|
|
35209
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35210
|
+
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * rowHeight - rowHeight * 3);
|
|
35211
|
+
}
|
|
34890
35212
|
renderFn();
|
|
34891
35213
|
}).catch(() => {
|
|
34892
35214
|
if (version !== searchVersion)
|
|
@@ -34907,7 +35229,8 @@ code-viewer query agent-help`
|
|
|
34907
35229
|
return;
|
|
34908
35230
|
active = (active + direction + matches.length) % matches.length;
|
|
34909
35231
|
count.textContent = `${active + 1} / ${matches.length}`;
|
|
34910
|
-
|
|
35232
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35233
|
+
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * rowHeight - rowHeight * 3);
|
|
34911
35234
|
renderFn();
|
|
34912
35235
|
};
|
|
34913
35236
|
input2.addEventListener("input", () => {
|
|
@@ -35001,7 +35324,7 @@ code-viewer query agent-help`
|
|
|
35001
35324
|
scroller.setAttribute("aria-label", `${target.path} source code`);
|
|
35002
35325
|
const spacer = document.createElement("div");
|
|
35003
35326
|
spacer.className = "gdp-source-virtual-spacer";
|
|
35004
|
-
spacer.style.height = `${Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
|
|
35327
|
+
spacer.style.height = `${Math.max(1, lines.length * (sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT))}px`;
|
|
35005
35328
|
const windowEl = document.createElement("div");
|
|
35006
35329
|
windowEl.className = "gdp-source-virtual-window";
|
|
35007
35330
|
spacer.appendChild(windowEl);
|
|
@@ -35010,19 +35333,23 @@ code-viewer query agent-help`
|
|
|
35010
35333
|
let raf = 0;
|
|
35011
35334
|
let renderedStart = -1;
|
|
35012
35335
|
let renderedEnd = -1;
|
|
35336
|
+
let renderedRowHeight = -1;
|
|
35013
35337
|
let search = null;
|
|
35014
35338
|
const render = () => {
|
|
35015
35339
|
raf = 0;
|
|
35340
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35341
|
+
spacer.style.height = `${Math.max(1, lines.length * rowHeight)}px`;
|
|
35016
35342
|
const viewportHeight = scroller.clientHeight || window.innerHeight;
|
|
35017
35343
|
const overscan = 20;
|
|
35018
|
-
const start = Math.max(0, Math.floor(scroller.scrollTop /
|
|
35019
|
-
const end = Math.min(lines.length, Math.ceil((scroller.scrollTop + viewportHeight) /
|
|
35020
|
-
if (start === renderedStart && end === renderedEnd)
|
|
35344
|
+
const start = Math.max(0, Math.floor(scroller.scrollTop / rowHeight) - overscan);
|
|
35345
|
+
const end = Math.min(lines.length, Math.ceil((scroller.scrollTop + viewportHeight) / rowHeight) + overscan);
|
|
35346
|
+
if (start === renderedStart && end === renderedEnd && rowHeight === renderedRowHeight)
|
|
35021
35347
|
return;
|
|
35022
35348
|
renderedStart = start;
|
|
35023
35349
|
renderedEnd = end;
|
|
35350
|
+
renderedRowHeight = rowHeight;
|
|
35024
35351
|
windowEl.replaceChildren();
|
|
35025
|
-
windowEl.style.transform = `translateY(${start *
|
|
35352
|
+
windowEl.style.transform = `translateY(${start * rowHeight}px)`;
|
|
35026
35353
|
const fragment = document.createDocumentFragment();
|
|
35027
35354
|
for (let index = start;index < end; index++) {
|
|
35028
35355
|
const row = document.createElement("div");
|
|
@@ -35138,7 +35465,8 @@ code-viewer query agent-help`
|
|
|
35138
35465
|
const updateTotals = () => {
|
|
35139
35466
|
SOURCE_CURSOR_TOTALS.set(sourceCursorKey(target), totalRows);
|
|
35140
35467
|
summary.textContent = (complete ? totalRows.toLocaleString() : `${lines.size.toLocaleString()}+`) + " lines loaded from " + formatBytes(size) + ". More rows load as you scroll.";
|
|
35141
|
-
|
|
35468
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35469
|
+
spacer.style.height = `${Math.max(1, totalRows * rowHeight)}px`;
|
|
35142
35470
|
};
|
|
35143
35471
|
const loadPage = (line) => {
|
|
35144
35472
|
if (signal?.aborted || complete && line > totalRows)
|
|
@@ -35175,20 +35503,24 @@ code-viewer query agent-help`
|
|
|
35175
35503
|
let raf = 0;
|
|
35176
35504
|
let renderedStart = -1;
|
|
35177
35505
|
let renderedEnd = -1;
|
|
35506
|
+
let renderedRowHeight = -1;
|
|
35178
35507
|
let search = null;
|
|
35179
35508
|
let searchController = null;
|
|
35180
35509
|
const render = () => {
|
|
35181
35510
|
raf = 0;
|
|
35511
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35512
|
+
spacer.style.height = `${Math.max(1, totalRows * rowHeight)}px`;
|
|
35182
35513
|
const viewportHeight = scroller.clientHeight || window.innerHeight;
|
|
35183
35514
|
const overscan = 20;
|
|
35184
|
-
const start = Math.max(0, Math.floor(scroller.scrollTop /
|
|
35185
|
-
const end = Math.min(totalRows, Math.ceil((scroller.scrollTop + viewportHeight) /
|
|
35186
|
-
if (start === renderedStart && end === renderedEnd)
|
|
35515
|
+
const start = Math.max(0, Math.floor(scroller.scrollTop / rowHeight) - overscan);
|
|
35516
|
+
const end = Math.min(totalRows, Math.ceil((scroller.scrollTop + viewportHeight) / rowHeight) + overscan);
|
|
35517
|
+
if (start === renderedStart && end === renderedEnd && rowHeight === renderedRowHeight)
|
|
35187
35518
|
return;
|
|
35188
35519
|
renderedStart = start;
|
|
35189
35520
|
renderedEnd = end;
|
|
35521
|
+
renderedRowHeight = rowHeight;
|
|
35190
35522
|
windowEl.replaceChildren();
|
|
35191
|
-
windowEl.style.transform = `translateY(${start *
|
|
35523
|
+
windowEl.style.transform = `translateY(${start * rowHeight}px)`;
|
|
35192
35524
|
const fragment = document.createDocumentFragment();
|
|
35193
35525
|
for (let index = start;index < end; index++) {
|
|
35194
35526
|
const lineNumber = index + 1;
|
|
@@ -35417,8 +35749,8 @@ code-viewer query agent-help`
|
|
|
35417
35749
|
scrollStandaloneSourceLine(mounted, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35418
35750
|
return;
|
|
35419
35751
|
}
|
|
35420
|
-
if (mounted && state === "loading")
|
|
35421
|
-
return;
|
|
35752
|
+
if (mounted && state === "loading" && mounted._loadPromise)
|
|
35753
|
+
return mounted._loadPromise;
|
|
35422
35754
|
}
|
|
35423
35755
|
cancelActiveSourceLoad("navigation");
|
|
35424
35756
|
const req = ++SOURCE_REQ_SEQ;
|
|
@@ -35442,7 +35774,8 @@ code-viewer query agent-help`
|
|
|
35442
35774
|
currentRange,
|
|
35443
35775
|
setRoute,
|
|
35444
35776
|
setPreferredSourceTab,
|
|
35445
|
-
createFileBreadcrumb
|
|
35777
|
+
createFileBreadcrumb,
|
|
35778
|
+
createRepositoryWebLink: createRepositoryWebLink2
|
|
35446
35779
|
}, target, activeTab, internalKind ? { includeFileTabs: false, previewable: false } : {});
|
|
35447
35780
|
const pathActions = header.querySelector(".gdp-file-detail-path") || header;
|
|
35448
35781
|
pathActions.appendChild(createOpenPathButton(target.path, "file-parent", "open parent folder in OS"));
|
|
@@ -35453,7 +35786,7 @@ code-viewer query agent-help`
|
|
|
35453
35786
|
loadRepo();
|
|
35454
35787
|
}));
|
|
35455
35788
|
}
|
|
35456
|
-
if (
|
|
35789
|
+
if (internalKind !== "git") {
|
|
35457
35790
|
loadRawFileInfo(target).then((meta) => {
|
|
35458
35791
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35459
35792
|
return;
|
|
@@ -35478,94 +35811,103 @@ code-viewer query agent-help`
|
|
|
35478
35811
|
wrapper.appendChild(detailBody);
|
|
35479
35812
|
card.appendChild(wrapper);
|
|
35480
35813
|
mountFileShellCard({ $, repoFileTargetFromRoute, renderRepoBlobSidebar, placeSidebarToggle }, target, card, repoTarget);
|
|
35481
|
-
if (internalKind) {
|
|
35482
|
-
renderSourceInternalPath(card, target
|
|
35814
|
+
if (internalKind === "git") {
|
|
35815
|
+
renderSourceInternalPath(card, target);
|
|
35483
35816
|
return;
|
|
35484
35817
|
}
|
|
35485
35818
|
const controller = new AbortController;
|
|
35486
35819
|
ACTIVE_SOURCE_LOAD = { controller, req, target, card };
|
|
35487
35820
|
renderSourceLoading(card, target, () => cancelActiveSourceLoad("user"));
|
|
35488
|
-
|
|
35489
|
-
|
|
35490
|
-
|
|
35491
|
-
|
|
35492
|
-
|
|
35493
|
-
|
|
35494
|
-
|
|
35495
|
-
|
|
35496
|
-
|
|
35821
|
+
const sourceLoad = (async () => {
|
|
35822
|
+
try {
|
|
35823
|
+
let displayKind = sourceDisplayKind(target.path);
|
|
35824
|
+
let rawInfo = null;
|
|
35825
|
+
if (displayKind === "unsupported") {
|
|
35826
|
+
rawInfo = await loadRawFileInfo(target);
|
|
35827
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35828
|
+
return;
|
|
35829
|
+
if (await sourceLooksTextByContent(target, rawInfo, controller.signal)) {
|
|
35830
|
+
displayKind = "text";
|
|
35831
|
+
}
|
|
35497
35832
|
}
|
|
35498
|
-
|
|
35499
|
-
|
|
35500
|
-
|
|
35501
|
-
|
|
35502
|
-
|
|
35503
|
-
renderSourceUnsupported(card, target);
|
|
35504
|
-
return;
|
|
35505
|
-
}
|
|
35506
|
-
if (displayKind === "image" || displayKind === "video" || displayKind === "audio" || displayKind === "pdf") {
|
|
35507
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35833
|
+
if (displayKind === "unsupported") {
|
|
35834
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35835
|
+
return;
|
|
35836
|
+
finishSourceLoad(req);
|
|
35837
|
+
renderSourceUnsupported(card, target);
|
|
35508
35838
|
return;
|
|
35509
|
-
|
|
35510
|
-
|
|
35511
|
-
|
|
35512
|
-
|
|
35513
|
-
|
|
35514
|
-
|
|
35515
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35839
|
+
}
|
|
35840
|
+
if (displayKind === "image" || displayKind === "video" || displayKind === "audio" || displayKind === "pdf") {
|
|
35841
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35842
|
+
return;
|
|
35843
|
+
finishSourceLoad(req);
|
|
35844
|
+
renderSourceMedia(card, target, displayKind);
|
|
35516
35845
|
return;
|
|
35517
|
-
|
|
35518
|
-
|
|
35846
|
+
}
|
|
35847
|
+
if (displayKind === "text") {
|
|
35848
|
+
const meta = rawInfo ?? await loadRawFileInfo(target);
|
|
35849
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35850
|
+
return;
|
|
35851
|
+
if (!isVirtualSourceDisabled() && meta.size != null && meta.size >= VIRTUAL_SOURCE_SIZE_THRESHOLD) {
|
|
35852
|
+
const rendered2 = await renderPagedSourceText(card, target, meta.size, controller.signal);
|
|
35853
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35854
|
+
return;
|
|
35855
|
+
if (!rendered2) {
|
|
35856
|
+
finishSourceLoad(req);
|
|
35857
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35858
|
+
return;
|
|
35859
|
+
}
|
|
35860
|
+
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35861
|
+
setSourceCardState(card, "done");
|
|
35862
|
+
finishSourceLoad(req);
|
|
35863
|
+
return;
|
|
35864
|
+
}
|
|
35865
|
+
const response = await trackLoad(fetch(buildRawFileUrl(target), { signal: controller.signal }));
|
|
35519
35866
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35520
35867
|
return;
|
|
35521
|
-
if (!
|
|
35868
|
+
if (!response.ok) {
|
|
35522
35869
|
finishSourceLoad(req);
|
|
35523
35870
|
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35524
35871
|
return;
|
|
35525
35872
|
}
|
|
35873
|
+
const textValue = await response.text();
|
|
35874
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35875
|
+
return;
|
|
35876
|
+
const rendered = await renderSourceText(card, target, textValue, controller.signal);
|
|
35877
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35878
|
+
return;
|
|
35879
|
+
if (!rendered)
|
|
35880
|
+
return;
|
|
35526
35881
|
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35527
35882
|
setSourceCardState(card, "done");
|
|
35528
35883
|
finishSourceLoad(req);
|
|
35529
|
-
return;
|
|
35530
35884
|
}
|
|
35531
|
-
|
|
35885
|
+
} catch (err) {
|
|
35532
35886
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35533
35887
|
return;
|
|
35534
|
-
|
|
35535
|
-
|
|
35536
|
-
|
|
35888
|
+
finishSourceLoad(req);
|
|
35889
|
+
if (isAbortError3(err)) {
|
|
35890
|
+
renderSourceCancelled(card, target);
|
|
35537
35891
|
return;
|
|
35538
35892
|
}
|
|
35539
|
-
|
|
35540
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35541
|
-
return;
|
|
35542
|
-
const rendered = await renderSourceText(card, target, textValue, controller.signal);
|
|
35543
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35544
|
-
return;
|
|
35545
|
-
if (!rendered)
|
|
35546
|
-
return;
|
|
35547
|
-
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35548
|
-
setSourceCardState(card, "done");
|
|
35549
|
-
finishSourceLoad(req);
|
|
35550
|
-
}
|
|
35551
|
-
} catch (err) {
|
|
35552
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35553
|
-
return;
|
|
35554
|
-
finishSourceLoad(req);
|
|
35555
|
-
if (isAbortError3(err)) {
|
|
35556
|
-
renderSourceCancelled(card, target);
|
|
35557
|
-
return;
|
|
35893
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35558
35894
|
}
|
|
35559
|
-
|
|
35560
|
-
|
|
35895
|
+
})();
|
|
35896
|
+
const completed = sourceLoad.finally(() => {
|
|
35897
|
+
if (card._loadPromise === completed)
|
|
35898
|
+
delete card._loadPromise;
|
|
35899
|
+
});
|
|
35900
|
+
card._loadPromise = completed;
|
|
35901
|
+
return completed;
|
|
35561
35902
|
}
|
|
35562
35903
|
function scrollStandaloneSourceLine(card, line) {
|
|
35563
35904
|
if (!line || line < 1)
|
|
35564
35905
|
return;
|
|
35565
35906
|
const virtualScroller = card.querySelector(".gdp-source-virtual-scroller");
|
|
35566
35907
|
if (virtualScroller) {
|
|
35567
|
-
const
|
|
35568
|
-
|
|
35908
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35909
|
+
const centeredOffset = virtualScroller.clientHeight / 2 - rowHeight / 2;
|
|
35910
|
+
virtualScroller.scrollTop = Math.max(0, (line - 1) * rowHeight - Math.max(0, centeredOffset));
|
|
35569
35911
|
virtualScroller.__gdpRenderVirtualSource?.();
|
|
35570
35912
|
return;
|
|
35571
35913
|
}
|
|
@@ -35689,6 +36031,8 @@ code-viewer query agent-help`
|
|
|
35689
36031
|
let PENDING_G_SCOPE = null;
|
|
35690
36032
|
let PENDING_G_UNTIL = 0;
|
|
35691
36033
|
let PROJECT_NAME = "";
|
|
36034
|
+
let PROJECT_BRANCH = "";
|
|
36035
|
+
let REPO_WEB_URL = null;
|
|
35692
36036
|
let APP_SETTINGS = { version: 1 };
|
|
35693
36037
|
let VIEW_STATE = {
|
|
35694
36038
|
version: 1,
|
|
@@ -35833,11 +36177,14 @@ code-viewer query agent-help`
|
|
|
35833
36177
|
}
|
|
35834
36178
|
}
|
|
35835
36179
|
function setProjectBranch(branch) {
|
|
36180
|
+
PROJECT_BRANCH = branch;
|
|
35836
36181
|
const el = document.querySelector("#project-branch");
|
|
35837
36182
|
if (!el)
|
|
35838
36183
|
return;
|
|
35839
36184
|
el.hidden = !branch;
|
|
35840
|
-
|
|
36185
|
+
const name = el.querySelector(".project-branch-name");
|
|
36186
|
+
if (name)
|
|
36187
|
+
name.textContent = branch;
|
|
35841
36188
|
el.title = branch ? `Current branch: ${branch}` : "";
|
|
35842
36189
|
}
|
|
35843
36190
|
function mergeLocalSettings(patch) {
|
|
@@ -36024,7 +36371,14 @@ code-viewer query agent-help`
|
|
|
36024
36371
|
return normalizeViewerFontSize(APP_SETTINGS.codeFontSize);
|
|
36025
36372
|
}
|
|
36026
36373
|
function applyCodeFontSize(size = savedCodeFontSize()) {
|
|
36374
|
+
const previousLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
36027
36375
|
document.body.dataset.codeFontSize = size;
|
|
36376
|
+
const nextLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
36377
|
+
document.querySelectorAll(".gdp-source-virtual-scroller").forEach((scroller) => {
|
|
36378
|
+
if (Number.isFinite(previousLineHeight) && previousLineHeight > 0 && Number.isFinite(nextLineHeight) && nextLineHeight > 0)
|
|
36379
|
+
scroller.scrollTop *= nextLineHeight / previousLineHeight;
|
|
36380
|
+
scroller.__gdpRenderVirtualSource?.();
|
|
36381
|
+
});
|
|
36028
36382
|
}
|
|
36029
36383
|
function savedSidebarFontSizeSetting() {
|
|
36030
36384
|
return normalizeViewerFontSize(APP_SETTINGS.sidebarFontSize);
|
|
@@ -36057,10 +36411,11 @@ code-viewer query agent-help`
|
|
|
36057
36411
|
const settings = await res.json();
|
|
36058
36412
|
setProjectName(settings.project || "");
|
|
36059
36413
|
setProjectBranch(settings.branch || "");
|
|
36414
|
+
REPO_WEB_URL = settings.repo_web_url;
|
|
36060
36415
|
const repoLink = document.querySelector("#repo-web-link");
|
|
36061
|
-
if (repoLink
|
|
36062
|
-
repoLink.href = settings.repo_web_url;
|
|
36063
|
-
repoLink.hidden =
|
|
36416
|
+
if (repoLink) {
|
|
36417
|
+
repoLink.href = settings.repo_web_url || "#";
|
|
36418
|
+
repoLink.hidden = !settings.repo_web_url;
|
|
36064
36419
|
}
|
|
36065
36420
|
SERVER_SCOPE_OMIT_DIRS_DEFAULT = normalizeScopeOmitDirs(settings.scope.omit_dirs_effective);
|
|
36066
36421
|
SERVER_SCOPE_EXCLUDE_NAMES_DEFAULT = normalizeScopeExcludeNames(settings.scope.exclude_names_effective);
|
|
@@ -36157,7 +36512,24 @@ code-viewer query agent-help`
|
|
|
36157
36512
|
const LINE_REF_PILL = createLineRefPill({
|
|
36158
36513
|
onClose: () => {
|
|
36159
36514
|
clearLineSelection();
|
|
36160
|
-
}
|
|
36515
|
+
},
|
|
36516
|
+
githubUrlForSelection: (path, start, end) => {
|
|
36517
|
+
const route = STATE.route;
|
|
36518
|
+
const ref = route.screen === "file" ? route.commit || route.ref : route.screen === "diff" ? route.range.to : "worktree";
|
|
36519
|
+
const target = buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
36520
|
+
ref,
|
|
36521
|
+
fallbackRef: PROJECT_BRANCH,
|
|
36522
|
+
path,
|
|
36523
|
+
kind: "blob",
|
|
36524
|
+
start,
|
|
36525
|
+
end
|
|
36526
|
+
});
|
|
36527
|
+
return target?.provider === "github" ? target.url : null;
|
|
36528
|
+
},
|
|
36529
|
+
copyReferenceLabel: () => uiText().global.copyLineReference,
|
|
36530
|
+
lineCountLabel: (count) => uiText().global.selectedLineCount(count),
|
|
36531
|
+
githubOpenTitle: () => uiText().global.githubSelectionOpen,
|
|
36532
|
+
githubCopyTitle: () => uiText().global.githubSelectionCopy
|
|
36161
36533
|
});
|
|
36162
36534
|
const DIFF_LINE_SELECT = createDiffLineSelect({ pill: LINE_REF_PILL });
|
|
36163
36535
|
function clearRenderedSourceLineTargets() {
|
|
@@ -36308,6 +36680,7 @@ code-viewer query agent-help`
|
|
|
36308
36680
|
renderRepoBlobSidebar: (path, ref) => REPO_VIEW.renderRepoBlobSidebar(path, ref),
|
|
36309
36681
|
placeSidebarToggle,
|
|
36310
36682
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
36683
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
36311
36684
|
createFileDetailMeta: (target, meta) => REPO_VIEW.createFileDetailMeta(target, meta),
|
|
36312
36685
|
createOpenPathButton,
|
|
36313
36686
|
createMoveToTrashButton: (path, onDeleted) => REPO_VIEW.createMoveToTrashButton(path, onDeleted),
|
|
@@ -36341,7 +36714,7 @@ code-viewer query agent-help`
|
|
|
36341
36714
|
currentRange,
|
|
36342
36715
|
trackLoad,
|
|
36343
36716
|
getSyntaxHighlight: () => STATE.syntaxHighlight,
|
|
36344
|
-
loadSourceShikiHighlighter: () => SOURCE_VIEW.loadSourceShikiHighlighter(),
|
|
36717
|
+
loadSourceShikiHighlighter: (lang) => SOURCE_VIEW.loadSourceShikiHighlighter(lang),
|
|
36345
36718
|
sourceShikiLines: (textValue, lang, highlighter) => SOURCE_VIEW.sourceShikiLines(textValue, lang, highlighter),
|
|
36346
36719
|
inferLang: (path) => SOURCE_VIEW.inferLang(path),
|
|
36347
36720
|
currentSourceLineTarget: (target) => SOURCE_VIEW.currentSourceLineTarget(target),
|
|
@@ -36349,6 +36722,7 @@ code-viewer query agent-help`
|
|
|
36349
36722
|
bindSourceLineNumber: (num, card, target, line) => SOURCE_VIEW.bindSourceLineNumber(num, card, target, line),
|
|
36350
36723
|
setPreferredSourceTab: (tab) => SOURCE_VIEW.setPreferredSourceTab(tab),
|
|
36351
36724
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
36725
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
36352
36726
|
removeStandaloneSource,
|
|
36353
36727
|
placeSidebarToggle,
|
|
36354
36728
|
escapeHtml: escapeHtml3,
|
|
@@ -36423,6 +36797,14 @@ code-viewer query agent-help`
|
|
|
36423
36797
|
const text3 = uiText().repo;
|
|
36424
36798
|
return submodule ? { label: text3.submoduleLabel, title: text3.submoduleTitle } : { label: text3.gitlinkLabel, title: text3.gitlinkTitle };
|
|
36425
36799
|
},
|
|
36800
|
+
repositoryWebTarget: (path, ref) => buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
36801
|
+
ref,
|
|
36802
|
+
fallbackRef: PROJECT_BRANCH,
|
|
36803
|
+
path,
|
|
36804
|
+
kind: "tree"
|
|
36805
|
+
}),
|
|
36806
|
+
openGithubLabel: () => uiText().repo.openGithub,
|
|
36807
|
+
openRepositoryWebLabel: () => uiText().repo.openRepositoryWeb,
|
|
36426
36808
|
fileBadge: (status) => DIFF_VIEW.fileBadge(status)
|
|
36427
36809
|
});
|
|
36428
36810
|
const {
|
|
@@ -36465,9 +36847,7 @@ code-viewer query agent-help`
|
|
|
36465
36847
|
queryHistory: "query history",
|
|
36466
36848
|
settings: "viewer settings",
|
|
36467
36849
|
theme: "toggle theme",
|
|
36468
|
-
product: "code viewer",
|
|
36469
36850
|
copyAiContext: "Copy AI context (Shift+Click to include code)",
|
|
36470
|
-
copyAiContextLabel: "AI context",
|
|
36471
36851
|
copyAiContextCopied: "Copied AI context",
|
|
36472
36852
|
copyAiContextCopiedWithCode: (lines) => `Copied AI context + code (${lines} line${lines === 1 ? "" : "s"})`,
|
|
36473
36853
|
copyAiContextFailed: "Copy failed",
|
|
@@ -36480,7 +36860,12 @@ code-viewer query agent-help`
|
|
|
36480
36860
|
cancelRequestsActiveTitle: (count) => `cancel ${count} in-flight request${count === 1 ? "" : "s"}`,
|
|
36481
36861
|
cancelRequestsInactiveTitle: "no in-flight requests",
|
|
36482
36862
|
brandHome: "Repository home",
|
|
36483
|
-
menuViews: "Views"
|
|
36863
|
+
menuViews: "Views",
|
|
36864
|
+
repoWebLink: "open repository web page",
|
|
36865
|
+
copyLineReference: "Copy AI reference",
|
|
36866
|
+
selectedLineCount: (count) => `${count} line${count === 1 ? "" : "s"}`,
|
|
36867
|
+
githubSelectionOpen: "Open selected lines on GitHub",
|
|
36868
|
+
githubSelectionCopy: "Copy GitHub link"
|
|
36484
36869
|
},
|
|
36485
36870
|
topbar: {
|
|
36486
36871
|
resetRange: "reset to HEAD .. worktree",
|
|
@@ -36491,15 +36876,13 @@ code-viewer query agent-help`
|
|
|
36491
36876
|
ignoreWs: "ignore whitespace changes (-w)",
|
|
36492
36877
|
ignoreWsLabel: "ws",
|
|
36493
36878
|
syntaxLoading: "loading...",
|
|
36494
|
-
|
|
36495
|
-
syntaxOff: "syntax off",
|
|
36879
|
+
syntax: "syntax",
|
|
36496
36880
|
syntaxOnTitle: "syntax highlighting on",
|
|
36497
36881
|
syntaxLoadingTitle: "loading syntax highlighter",
|
|
36498
36882
|
syntaxErrorTitle: "failed to load syntax highlighter",
|
|
36499
36883
|
syntaxOffTitle: "syntax highlighting off",
|
|
36500
36884
|
hideTests: "hide test files (test|spec)",
|
|
36501
36885
|
hideTestsLabel: "no test",
|
|
36502
|
-
autoUpdate: "auto",
|
|
36503
36886
|
autoUpdateOnTitle: "auto update on file change",
|
|
36504
36887
|
autoUpdateOffTitle: "auto update off — manual reload"
|
|
36505
36888
|
},
|
|
@@ -36586,7 +36969,9 @@ code-viewer query agent-help`
|
|
|
36586
36969
|
gitlinkLabel: "gitlink",
|
|
36587
36970
|
gitlinkTitle: "Git commit entry is not directly browsable at this ref",
|
|
36588
36971
|
submoduleLabel: "submodule",
|
|
36589
|
-
submoduleTitle: "Git submodule pinned to a commit"
|
|
36972
|
+
submoduleTitle: "Git submodule pinned to a commit",
|
|
36973
|
+
openGithub: "Open on GitHub",
|
|
36974
|
+
openRepositoryWeb: "Open repository web page"
|
|
36590
36975
|
},
|
|
36591
36976
|
history: {
|
|
36592
36977
|
title: "Commits",
|
|
@@ -36703,7 +37088,7 @@ code-viewer query agent-help`
|
|
|
36703
37088
|
display: "Display",
|
|
36704
37089
|
language: "Language",
|
|
36705
37090
|
fileListFontSize: "UI font size",
|
|
36706
|
-
fileListFontSizeHelp: "Applies to
|
|
37091
|
+
fileListFontSizeHelp: "Applies to all UI except code content.",
|
|
36707
37092
|
codeFontSize: "Code font size",
|
|
36708
37093
|
sizeSmall: "Small",
|
|
36709
37094
|
sizeRegular: "Regular",
|
|
@@ -36755,9 +37140,7 @@ code-viewer query agent-help`
|
|
|
36755
37140
|
queryHistory: "クエリ履歴",
|
|
36756
37141
|
settings: "ビューア設定",
|
|
36757
37142
|
theme: "テーマ切り替え",
|
|
36758
|
-
product: "code viewer",
|
|
36759
37143
|
copyAiContext: "AI 用コンテキストをコピー(Shift+Click でコードも添付)",
|
|
36760
|
-
copyAiContextLabel: "AI文脈",
|
|
36761
37144
|
copyAiContextCopied: "コピーしました",
|
|
36762
37145
|
copyAiContextCopiedWithCode: (lines) => `コピーしました(コード付き・${lines}行)`,
|
|
36763
37146
|
copyAiContextFailed: "コピーに失敗しました",
|
|
@@ -36770,7 +37153,12 @@ code-viewer query agent-help`
|
|
|
36770
37153
|
cancelRequestsActiveTitle: (count) => `実行中のリクエストを${count}件キャンセル`,
|
|
36771
37154
|
cancelRequestsInactiveTitle: "実行中のリクエストはありません",
|
|
36772
37155
|
brandHome: "リポジトリホーム",
|
|
36773
|
-
menuViews: "ビュー切り替え"
|
|
37156
|
+
menuViews: "ビュー切り替え",
|
|
37157
|
+
repoWebLink: "リポジトリのウェブページを開く",
|
|
37158
|
+
copyLineReference: "AI参照をコピー",
|
|
37159
|
+
selectedLineCount: (count) => `${count}行`,
|
|
37160
|
+
githubSelectionOpen: "選択行をGitHubで開く",
|
|
37161
|
+
githubSelectionCopy: "GitHubリンクをコピー"
|
|
36774
37162
|
},
|
|
36775
37163
|
topbar: {
|
|
36776
37164
|
resetRange: "HEAD .. worktree に戻す",
|
|
@@ -36781,15 +37169,13 @@ code-viewer query agent-help`
|
|
|
36781
37169
|
ignoreWs: "空白差分を無視 (-w)",
|
|
36782
37170
|
ignoreWsLabel: "空白",
|
|
36783
37171
|
syntaxLoading: "読み込み中...",
|
|
36784
|
-
|
|
36785
|
-
syntaxOff: "構文なし",
|
|
37172
|
+
syntax: "構文",
|
|
36786
37173
|
syntaxOnTitle: "シンタックスハイライト有効",
|
|
36787
37174
|
syntaxLoadingTitle: "シンタックスハイライトを読み込み中",
|
|
36788
37175
|
syntaxErrorTitle: "シンタックスハイライトの読み込みに失敗",
|
|
36789
37176
|
syntaxOffTitle: "シンタックスハイライト無効",
|
|
36790
37177
|
hideTests: "test/spec ファイルを隠す",
|
|
36791
37178
|
hideTestsLabel: "テスト非表示",
|
|
36792
|
-
autoUpdate: "自動",
|
|
36793
37179
|
autoUpdateOnTitle: "ファイル変更時に自動更新",
|
|
36794
37180
|
autoUpdateOffTitle: "自動更新オフ — 手動で再読み込み"
|
|
36795
37181
|
},
|
|
@@ -36876,7 +37262,9 @@ code-viewer query agent-help`
|
|
|
36876
37262
|
gitlinkLabel: "固定コミット",
|
|
36877
37263
|
gitlinkTitle: "特定のコミットに固定された参照です。この ref では直接開けません。",
|
|
36878
37264
|
submoduleLabel: "サブモジュール",
|
|
36879
|
-
submoduleTitle: "Git サブモジュール: 特定のコミットに固定されています。直接は開けません。"
|
|
37265
|
+
submoduleTitle: "Git サブモジュール: 特定のコミットに固定されています。直接は開けません。",
|
|
37266
|
+
openGithub: "GitHubで開く",
|
|
37267
|
+
openRepositoryWeb: "リポジトリのウェブページを開く"
|
|
36880
37268
|
},
|
|
36881
37269
|
history: {
|
|
36882
37270
|
title: "コミット",
|
|
@@ -36993,7 +37381,7 @@ code-viewer query agent-help`
|
|
|
36993
37381
|
display: "表示",
|
|
36994
37382
|
language: "言語",
|
|
36995
37383
|
fileListFontSize: "UIの文字サイズ",
|
|
36996
|
-
fileListFontSizeHelp: "
|
|
37384
|
+
fileListFontSizeHelp: "コード本文を除くUI全体に適用されます。",
|
|
36997
37385
|
codeFontSize: "コード表示の文字サイズ",
|
|
36998
37386
|
sizeSmall: "小",
|
|
36999
37387
|
sizeRegular: "標準",
|
|
@@ -37059,8 +37447,16 @@ code-viewer query agent-help`
|
|
|
37059
37447
|
if (route && text3.nav[route])
|
|
37060
37448
|
link2.textContent = text3.nav[route];
|
|
37061
37449
|
});
|
|
37062
|
-
|
|
37063
|
-
|
|
37450
|
+
const helpLink = document.querySelector(".global-icon-link[data-route='help']");
|
|
37451
|
+
if (helpLink) {
|
|
37452
|
+
helpLink.title = text3.nav.help;
|
|
37453
|
+
helpLink.setAttribute("aria-label", text3.nav.help);
|
|
37454
|
+
}
|
|
37455
|
+
const repoWebLink = document.querySelector("#repo-web-link");
|
|
37456
|
+
if (repoWebLink) {
|
|
37457
|
+
repoWebLink.title = text3.global.repoWebLink;
|
|
37458
|
+
repoWebLink.setAttribute("aria-label", text3.global.repoWebLink);
|
|
37459
|
+
}
|
|
37064
37460
|
document.querySelector(".brand")?.setAttribute("aria-label", text3.global.brandHome);
|
|
37065
37461
|
document.querySelector(".app-menu")?.setAttribute("aria-label", text3.global.menuViews);
|
|
37066
37462
|
const annotationsToggle = document.querySelector("#annotations-toggle");
|
|
@@ -37095,9 +37491,6 @@ code-viewer query agent-help`
|
|
|
37095
37491
|
if (copyAiContext) {
|
|
37096
37492
|
copyAiContext.title = text3.global.copyAiContext;
|
|
37097
37493
|
copyAiContext.setAttribute("aria-label", text3.global.copyAiContext);
|
|
37098
|
-
const copyAiContextLabel = copyAiContext.querySelector(".ai-context-label");
|
|
37099
|
-
if (copyAiContextLabel)
|
|
37100
|
-
copyAiContextLabel.textContent = text3.global.copyAiContextLabel;
|
|
37101
37494
|
}
|
|
37102
37495
|
const refReset = document.querySelector("#ref-reset");
|
|
37103
37496
|
if (refReset) {
|
|
@@ -37301,6 +37694,7 @@ code-viewer query agent-help`
|
|
|
37301
37694
|
if (!hljsRef)
|
|
37302
37695
|
return null;
|
|
37303
37696
|
ensureTerraformHighlightLanguage(hljsRef);
|
|
37697
|
+
ensureGdscriptHighlightLanguage(hljsRef);
|
|
37304
37698
|
if (!highlightConfigured && typeof hljsRef.configure === "function") {
|
|
37305
37699
|
hljsRef.configure({ ignoreUnescapedHTML: true });
|
|
37306
37700
|
highlightConfigured = true;
|
|
@@ -37314,7 +37708,7 @@ code-viewer query agent-help`
|
|
|
37314
37708
|
const text3 = uiText();
|
|
37315
37709
|
btn.classList.toggle("active", STATE.syntaxHighlight);
|
|
37316
37710
|
btn.classList.toggle("loading", state === "loading");
|
|
37317
|
-
btn.textContent = state === "loading" ? text3.topbar.syntaxLoading :
|
|
37711
|
+
btn.textContent = state === "loading" ? text3.topbar.syntaxLoading : text3.topbar.syntax;
|
|
37318
37712
|
btn.setAttribute("aria-pressed", STATE.syntaxHighlight ? "true" : "false");
|
|
37319
37713
|
btn.title = STATE.syntaxHighlight ? text3.topbar.syntaxOnTitle : state === "loading" ? text3.topbar.syntaxLoadingTitle : state === "error" ? text3.topbar.syntaxErrorTitle : text3.topbar.syntaxOffTitle;
|
|
37320
37714
|
}
|
|
@@ -37699,6 +38093,7 @@ code-viewer query agent-help`
|
|
|
37699
38093
|
setRoute,
|
|
37700
38094
|
setPreferredSourceTab: (tab) => SOURCE_VIEW.setPreferredSourceTab(tab),
|
|
37701
38095
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
38096
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
37702
38097
|
emptyText: () => uiText().diff
|
|
37703
38098
|
}, historyRoute, { loadSidebar: false });
|
|
37704
38099
|
activeFileHistoryDiffHost = mount.diffHost;
|
|
@@ -37874,7 +38269,7 @@ code-viewer query agent-help`
|
|
|
37874
38269
|
applyHideTests();
|
|
37875
38270
|
}
|
|
37876
38271
|
function syncHeaderMenu() {
|
|
37877
|
-
document.querySelectorAll(".app-menu-item, .global-
|
|
38272
|
+
document.querySelectorAll(".app-menu-item, .global-icon-link").forEach((link2) => {
|
|
37878
38273
|
const fileRouteOwner = STATE.route.screen === "file" && (STATE.route.view === "blob" || STATE.route.view === "blame" || STATE.route.view === "history") ? "repo" : "diff";
|
|
37879
38274
|
const active = link2.dataset.route === STATE.route.screen || STATE.route.screen === "file" && link2.dataset.route === fileRouteOwner;
|
|
37880
38275
|
link2.classList.toggle("active", active);
|
|
@@ -37999,6 +38394,18 @@ code-viewer query agent-help`
|
|
|
37999
38394
|
});
|
|
38000
38395
|
return button;
|
|
38001
38396
|
}
|
|
38397
|
+
function createFileRepositoryWebLink(target) {
|
|
38398
|
+
const webTarget = buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
38399
|
+
ref: target.ref,
|
|
38400
|
+
fallbackRef: PROJECT_BRANCH,
|
|
38401
|
+
path: target.path,
|
|
38402
|
+
kind: "blob"
|
|
38403
|
+
});
|
|
38404
|
+
if (!webTarget)
|
|
38405
|
+
return null;
|
|
38406
|
+
const label = webTarget.provider === "github" ? uiText().repo.openGithub : uiText().repo.openRepositoryWeb;
|
|
38407
|
+
return createRepositoryWebLink(webTarget, label);
|
|
38408
|
+
}
|
|
38002
38409
|
window.addEventListener("scroll", () => enqueueInitialLoads(), {
|
|
38003
38410
|
passive: true
|
|
38004
38411
|
});
|
|
@@ -38108,14 +38515,34 @@ code-viewer query agent-help`
|
|
|
38108
38515
|
if (cancelRequestsIcon) {
|
|
38109
38516
|
cancelRequestsIcon.innerHTML = iconSvg("octicon-x", X_16_PATH);
|
|
38110
38517
|
}
|
|
38518
|
+
const repoWebLinkIcon = document.querySelector("#repo-web-link .goi-icon");
|
|
38519
|
+
if (repoWebLinkIcon) {
|
|
38520
|
+
repoWebLinkIcon.innerHTML = iconSvg("octicon-mark-github", MARK_GITHUB_16_PATH);
|
|
38521
|
+
}
|
|
38522
|
+
const quickHelpIcon = document.querySelector("#quick-help-btn .goi-icon");
|
|
38523
|
+
if (quickHelpIcon) {
|
|
38524
|
+
quickHelpIcon.innerHTML = iconSvg("octicon-question", QUESTION_16_PATH);
|
|
38525
|
+
}
|
|
38526
|
+
const helpLinkIcon = document.querySelector(".global-icon-link[data-route='help'] .goi-icon");
|
|
38527
|
+
if (helpLinkIcon) {
|
|
38528
|
+
helpLinkIcon.innerHTML = iconSvg("octicon-book", BOOK_16_PATH);
|
|
38529
|
+
}
|
|
38530
|
+
const branchIcon = document.querySelector("#project-branch .goi-icon");
|
|
38531
|
+
if (branchIcon) {
|
|
38532
|
+
branchIcon.innerHTML = iconSvg("octicon-git-branch", GIT_BRANCH_16_PATH);
|
|
38533
|
+
}
|
|
38111
38534
|
}
|
|
38112
38535
|
function setRefActionIcons() {
|
|
38113
38536
|
const refReset = document.querySelector("#ref-reset");
|
|
38114
38537
|
if (refReset)
|
|
38115
|
-
refReset.innerHTML = iconSvg("octicon-
|
|
38538
|
+
refReset.innerHTML = iconSvg("octicon-undo", UNDO_16_PATH);
|
|
38116
38539
|
const reload = document.querySelector("#reload-prom");
|
|
38117
38540
|
if (reload)
|
|
38118
38541
|
reload.innerHTML = iconSvg("octicon-sync", SYNC_16_PATH);
|
|
38542
|
+
const refDots = document.querySelector(".ref-dots .goi-icon");
|
|
38543
|
+
if (refDots) {
|
|
38544
|
+
refDots.innerHTML = iconSvg("octicon-arrow-right", ARROW_RIGHT_16_PATH);
|
|
38545
|
+
}
|
|
38119
38546
|
}
|
|
38120
38547
|
applySidebarFontSize();
|
|
38121
38548
|
applyCodeFontSize();
|
|
@@ -39136,7 +39563,7 @@ code-viewer query agent-help`
|
|
|
39136
39563
|
}
|
|
39137
39564
|
window.addEventListener("popstate", applyRouteFromLocation);
|
|
39138
39565
|
window.addEventListener("pagehide", () => flushViewStatePatch(true));
|
|
39139
|
-
document.querySelectorAll(".app-menu-item, .global-
|
|
39566
|
+
document.querySelectorAll(".app-menu-item, .global-icon-link").forEach((link2) => {
|
|
39140
39567
|
if (link2.target === "_blank")
|
|
39141
39568
|
return;
|
|
39142
39569
|
link2.addEventListener("click", (e2) => {
|
|
@@ -39371,9 +39798,6 @@ code-viewer query agent-help`
|
|
|
39371
39798
|
btn.title = autoUpdateTitle;
|
|
39372
39799
|
btn.setAttribute("aria-label", autoUpdateTitle);
|
|
39373
39800
|
btn.setAttribute("aria-pressed", STATE.autoUpdate ? "true" : "false");
|
|
39374
|
-
const label = btn.querySelector(".auto-update-label");
|
|
39375
|
-
if (label)
|
|
39376
|
-
label.textContent = text3.topbar.autoUpdate;
|
|
39377
39801
|
}
|
|
39378
39802
|
function setAutoUpdate(on) {
|
|
39379
39803
|
STATE.autoUpdate = on;
|