@youtyan/code-viewer 0.8.6 → 0.8.8
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 +13 -3
- package/dist/code-viewer.js +45 -24
- package/package.json +1 -1
- package/web/app.js +719 -286
- package/web/index.html +10 -9
- package/web/style.css +1548 -366
package/web/app.js
CHANGED
|
@@ -227,6 +227,8 @@ ${lines.join(`
|
|
|
227
227
|
function shouldAutoLoadForRoute(route, options = {}) {
|
|
228
228
|
if (route.screen === "history")
|
|
229
229
|
return options.historyWorktreeSelected === true;
|
|
230
|
+
if (route.screen === "diff")
|
|
231
|
+
return !route.range.from || route.range.from === "worktree" || !route.range.to || route.range.to === "worktree";
|
|
230
232
|
if (route.screen === "database" || route.screen === "journal" || route.screen === "help" || route.screen === "unknown")
|
|
231
233
|
return false;
|
|
232
234
|
return true;
|
|
@@ -511,6 +513,8 @@ ${lines.join(`
|
|
|
511
513
|
];
|
|
512
514
|
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";
|
|
513
515
|
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";
|
|
516
|
+
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";
|
|
517
|
+
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";
|
|
514
518
|
function iconSvg(className, paths) {
|
|
515
519
|
const pathList = Array.isArray(paths) ? paths : [paths];
|
|
516
520
|
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>";
|
|
@@ -520,6 +524,9 @@ ${lines.join(`
|
|
|
520
524
|
var GRABBER_16_PATH = "M10 13h4v-2h-4v2Zm-8 0h4v-2H2v2Zm8-6h4V5h-4v2ZM2 7h4V5H2v2Zm8-6v2h4V1h-4ZM2 3h4V1H2v2Z";
|
|
521
525
|
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";
|
|
522
526
|
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";
|
|
527
|
+
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";
|
|
528
|
+
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";
|
|
529
|
+
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";
|
|
523
530
|
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";
|
|
524
531
|
var DOWNLOAD_16_PATHS = [
|
|
525
532
|
"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",
|
|
@@ -776,6 +783,50 @@ ${lines.join(`
|
|
|
776
783
|
};
|
|
777
784
|
}
|
|
778
785
|
|
|
786
|
+
// web-src/core/repository-web-url.ts
|
|
787
|
+
function encodePath(value) {
|
|
788
|
+
return value.split("/").filter(Boolean).map((part) => encodeURIComponent(part)).join("/");
|
|
789
|
+
}
|
|
790
|
+
function resolvedRef(ref, fallbackRef) {
|
|
791
|
+
if (!ref || ref === "worktree" || ref === "HEAD") {
|
|
792
|
+
return fallbackRef || "HEAD";
|
|
793
|
+
}
|
|
794
|
+
return ref;
|
|
795
|
+
}
|
|
796
|
+
function buildRepositoryWebTarget(repoWebUrl, options) {
|
|
797
|
+
if (!repoWebUrl)
|
|
798
|
+
return null;
|
|
799
|
+
let remote;
|
|
800
|
+
try {
|
|
801
|
+
remote = new URL(repoWebUrl);
|
|
802
|
+
} catch {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
if (remote.protocol !== "http:" && remote.protocol !== "https:")
|
|
806
|
+
return null;
|
|
807
|
+
remote.search = "";
|
|
808
|
+
remote.hash = "";
|
|
809
|
+
remote.pathname = remote.pathname.replace(/\/+$/, "");
|
|
810
|
+
const base = remote.toString().replace(/\/$/, "");
|
|
811
|
+
if (remote.hostname.toLowerCase() !== "github.com") {
|
|
812
|
+
return { url: base, provider: "web" };
|
|
813
|
+
}
|
|
814
|
+
const ref = encodePath(resolvedRef(options.ref, options.fallbackRef));
|
|
815
|
+
const path = encodePath(options.path || "");
|
|
816
|
+
if (!ref || options.kind === "blob" && !path) {
|
|
817
|
+
return { url: base, provider: "github" };
|
|
818
|
+
}
|
|
819
|
+
const pathSuffix = path ? `/${path}` : "";
|
|
820
|
+
const target = `${base}/${options.kind}/${ref}${pathSuffix}`;
|
|
821
|
+
if (options.kind !== "blob" || !Number.isFinite(options.start) || !Number.isFinite(options.end)) {
|
|
822
|
+
return { url: target, provider: "github" };
|
|
823
|
+
}
|
|
824
|
+
const start = Math.max(1, Math.floor(Math.min(options.start, options.end)));
|
|
825
|
+
const end = Math.max(1, Math.floor(Math.max(options.start, options.end)));
|
|
826
|
+
const lineHash = start === end ? `#L${start}` : `#L${start}-L${end}`;
|
|
827
|
+
return { url: `${target}${lineHash}`, provider: "github" };
|
|
828
|
+
}
|
|
829
|
+
|
|
779
830
|
// web-src/core/routes.ts
|
|
780
831
|
function assertNever(value) {
|
|
781
832
|
throw new Error(`unhandled route: ${JSON.stringify(value)}`);
|
|
@@ -1003,7 +1054,7 @@ ${lines.join(`
|
|
|
1003
1054
|
}
|
|
1004
1055
|
case "journal": {
|
|
1005
1056
|
const params = new URLSearchParams;
|
|
1006
|
-
if (route.tab && route.tab !== "
|
|
1057
|
+
if (route.tab && route.tab !== "tasks")
|
|
1007
1058
|
params.set("tab", route.tab);
|
|
1008
1059
|
if (route.date)
|
|
1009
1060
|
params.set("date", route.date);
|
|
@@ -8571,16 +8622,19 @@ ${frontmatter.yaml}
|
|
|
8571
8622
|
|
|
8572
8623
|
// web-src/views/annotations-ui.ts
|
|
8573
8624
|
var ANNOTATION_SESSION_PARAM = "annotationSession";
|
|
8625
|
+
var ANNOTATION_PANEL_PARAM = "annotations";
|
|
8626
|
+
var ANNOTATION_ENTRY_PARAM = "annotation";
|
|
8574
8627
|
function createAnnotationsUi(deps) {
|
|
8575
8628
|
const { $ } = deps;
|
|
8576
8629
|
let ANNOTATIONS = { version: 1, sessions: [] };
|
|
8577
8630
|
let annotationFollow = deps.getAnnotationFollow();
|
|
8578
|
-
|
|
8631
|
+
const initialUrlParams = new URLSearchParams(window.location.search);
|
|
8632
|
+
let activeAnnotationId = initialUrlParams.get(ANNOTATION_ENTRY_PARAM);
|
|
8579
8633
|
let refreshAnnotationsInFlight = null;
|
|
8580
8634
|
let inlineAnnotationsMounted = false;
|
|
8581
8635
|
let databaseAnnotationsMounted = false;
|
|
8582
8636
|
let annotationPanelDismissed = false;
|
|
8583
|
-
let activeSessionId =
|
|
8637
|
+
let activeSessionId = initialUrlParams.get(ANNOTATION_SESSION_PARAM);
|
|
8584
8638
|
const annotationsChangedCallbacks = [];
|
|
8585
8639
|
function notifyAnnotationsChanged() {
|
|
8586
8640
|
for (const cb of annotationsChangedCallbacks)
|
|
@@ -8637,8 +8691,14 @@ ${frontmatter.yaml}
|
|
|
8637
8691
|
if (qhPanel)
|
|
8638
8692
|
qhPanel.hidden = true;
|
|
8639
8693
|
document.body.classList.remove("query-history-panel-open");
|
|
8694
|
+
} else if (activeAnnotationId) {
|
|
8695
|
+
activeAnnotationId = null;
|
|
8696
|
+
annotationDetail.hidden = true;
|
|
8697
|
+
updateActiveHighlights();
|
|
8698
|
+
syncInlineAnnotationActive();
|
|
8640
8699
|
}
|
|
8641
8700
|
deps.setAnnotationPanelOpenState(open);
|
|
8701
|
+
syncSessionUrl();
|
|
8642
8702
|
applyInlineAnnotations();
|
|
8643
8703
|
}
|
|
8644
8704
|
function annotationLineTarget(entry) {
|
|
@@ -8686,13 +8746,33 @@ ${frontmatter.yaml}
|
|
|
8686
8746
|
}
|
|
8687
8747
|
function withSessionParam(rawUrl) {
|
|
8688
8748
|
const url = new URL(rawUrl, window.location.origin);
|
|
8749
|
+
if (!annotationPanel.hidden)
|
|
8750
|
+
url.searchParams.set(ANNOTATION_PANEL_PARAM, "open");
|
|
8751
|
+
else
|
|
8752
|
+
url.searchParams.delete(ANNOTATION_PANEL_PARAM);
|
|
8689
8753
|
if (activeSessionId)
|
|
8690
8754
|
url.searchParams.set(ANNOTATION_SESSION_PARAM, activeSessionId);
|
|
8691
8755
|
else
|
|
8692
8756
|
url.searchParams.delete(ANNOTATION_SESSION_PARAM);
|
|
8757
|
+
if (activeAnnotationId)
|
|
8758
|
+
url.searchParams.set(ANNOTATION_ENTRY_PARAM, activeAnnotationId);
|
|
8759
|
+
else
|
|
8760
|
+
url.searchParams.delete(ANNOTATION_ENTRY_PARAM);
|
|
8693
8761
|
return url.pathname + url.search;
|
|
8694
8762
|
}
|
|
8695
|
-
function
|
|
8763
|
+
function createStepChip(entry, step) {
|
|
8764
|
+
const chip = document.createElement("button");
|
|
8765
|
+
chip.type = "button";
|
|
8766
|
+
chip.className = "gdp-annotation-step";
|
|
8767
|
+
chip.textContent = `${step.index + 1}/${step.total}`;
|
|
8768
|
+
chip.title = `open step ${step.index + 1} of ${step.total}`;
|
|
8769
|
+
chip.setAttribute("aria-label", `open annotation step ${step.index + 1} of ${step.total}`);
|
|
8770
|
+
chip.addEventListener("click", () => {
|
|
8771
|
+
openAnnotationEntry(entry.id);
|
|
8772
|
+
});
|
|
8773
|
+
return chip;
|
|
8774
|
+
}
|
|
8775
|
+
function buildInlineAnnotationRow(entry, colSpan, step) {
|
|
8696
8776
|
const tr = document.createElement("tr");
|
|
8697
8777
|
tr.className = "gdp-annotation-row";
|
|
8698
8778
|
tr.dataset.annotationId = entry.id;
|
|
@@ -8701,13 +8781,17 @@ ${frontmatter.yaml}
|
|
|
8701
8781
|
td.colSpan = colSpan;
|
|
8702
8782
|
const box = document.createElement("div");
|
|
8703
8783
|
box.className = "gdp-annotation-inline";
|
|
8784
|
+
const head = document.createElement("div");
|
|
8785
|
+
head.className = "gdp-annotation-inline-head";
|
|
8786
|
+
head.appendChild(createStepChip(entry, step));
|
|
8704
8787
|
if (entry.title) {
|
|
8705
8788
|
const heading2 = document.createElement("strong");
|
|
8706
8789
|
heading2.className = "gdp-annotation-inline-title";
|
|
8707
8790
|
heading2.textContent = entry.title;
|
|
8708
|
-
|
|
8791
|
+
head.appendChild(heading2);
|
|
8709
8792
|
}
|
|
8710
|
-
|
|
8793
|
+
head.appendChild(createCopyRefButton(entry, "gdp-annotation-inline-copy"));
|
|
8794
|
+
box.appendChild(head);
|
|
8711
8795
|
const markdown = document.createElement("div");
|
|
8712
8796
|
markdown.className = "gdp-annotation-inline-body";
|
|
8713
8797
|
ensureMarkdownHighlighter();
|
|
@@ -8717,7 +8801,7 @@ ${frontmatter.yaml}
|
|
|
8717
8801
|
tr.appendChild(td);
|
|
8718
8802
|
return tr;
|
|
8719
8803
|
}
|
|
8720
|
-
function buildDatabaseAnnotationBlock(entry) {
|
|
8804
|
+
function buildDatabaseAnnotationBlock(entry, step) {
|
|
8721
8805
|
const box = document.createElement("div");
|
|
8722
8806
|
box.className = "gdp-db-annotation-inline";
|
|
8723
8807
|
box.dataset.annotationId = entry.id;
|
|
@@ -8734,7 +8818,7 @@ ${frontmatter.yaml}
|
|
|
8734
8818
|
const location2 = document.createElement("span");
|
|
8735
8819
|
location2.className = "gdp-db-annotation-inline-location";
|
|
8736
8820
|
location2.textContent = annotationLocationLabel(entry);
|
|
8737
|
-
head.append(title, location2, createCopyRefButton(entry));
|
|
8821
|
+
head.append(createStepChip(entry, step), title, location2, createCopyRefButton(entry));
|
|
8738
8822
|
const markdown = document.createElement("div");
|
|
8739
8823
|
markdown.className = "gdp-db-annotation-inline-body";
|
|
8740
8824
|
ensureMarkdownHighlighter();
|
|
@@ -8761,7 +8845,10 @@ ${frontmatter.yaml}
|
|
|
8761
8845
|
strip.className = "gdp-db-annotation-strip";
|
|
8762
8846
|
strip.setAttribute("aria-label", "Datastore annotations");
|
|
8763
8847
|
for (const entry of matches) {
|
|
8764
|
-
strip.appendChild(buildDatabaseAnnotationBlock(entry
|
|
8848
|
+
strip.appendChild(buildDatabaseAnnotationBlock(entry, {
|
|
8849
|
+
index: session.entries.indexOf(entry),
|
|
8850
|
+
total: session.entries.length
|
|
8851
|
+
}));
|
|
8765
8852
|
}
|
|
8766
8853
|
root.prepend(strip);
|
|
8767
8854
|
databaseAnnotationsMounted = true;
|
|
@@ -8836,16 +8923,19 @@ ${frontmatter.yaml}
|
|
|
8836
8923
|
if (!session)
|
|
8837
8924
|
return;
|
|
8838
8925
|
let mountedInlineRows = false;
|
|
8839
|
-
|
|
8926
|
+
session.entries.forEach((entry, index) => {
|
|
8840
8927
|
if (entry.target?.kind === "database")
|
|
8841
|
-
|
|
8928
|
+
return;
|
|
8842
8929
|
const target = inlineAnnotationTargetRow(entry);
|
|
8843
8930
|
if (!target)
|
|
8844
|
-
|
|
8931
|
+
return;
|
|
8845
8932
|
let anchor = target;
|
|
8846
8933
|
while (anchor.nextElementSibling?.classList.contains("gdp-annotation-row"))
|
|
8847
8934
|
anchor = anchor.nextElementSibling;
|
|
8848
|
-
anchor.after(buildInlineAnnotationRow(entry, target.cells.length
|
|
8935
|
+
anchor.after(buildInlineAnnotationRow(entry, target.cells.length, {
|
|
8936
|
+
index,
|
|
8937
|
+
total: session.entries.length
|
|
8938
|
+
}));
|
|
8849
8939
|
const sibling = siblingSideRow(target);
|
|
8850
8940
|
if (sibling) {
|
|
8851
8941
|
let sibAnchor = sibling;
|
|
@@ -8854,7 +8944,7 @@ ${frontmatter.yaml}
|
|
|
8854
8944
|
sibAnchor.after(buildInlineSpacerRow(entry, sibling.cells.length));
|
|
8855
8945
|
}
|
|
8856
8946
|
mountedInlineRows = true;
|
|
8857
|
-
}
|
|
8947
|
+
});
|
|
8858
8948
|
inlineAnnotationsMounted = mountedInlineRows;
|
|
8859
8949
|
syncInlineAnnotationWidths();
|
|
8860
8950
|
}
|
|
@@ -8893,14 +8983,21 @@ ${frontmatter.yaml}
|
|
|
8893
8983
|
if (activeSessionId === sessionId)
|
|
8894
8984
|
return;
|
|
8895
8985
|
activeSessionId = sessionId;
|
|
8986
|
+
activeAnnotationId = null;
|
|
8987
|
+
annotationDetail.hidden = true;
|
|
8896
8988
|
syncSessionUrl();
|
|
8897
8989
|
updateActiveHighlights();
|
|
8990
|
+
syncInlineAnnotationActive();
|
|
8898
8991
|
applyInlineAnnotations();
|
|
8899
8992
|
notifyAnnotationsChanged();
|
|
8900
8993
|
}
|
|
8901
8994
|
function restoreSessionFromUrl() {
|
|
8902
|
-
|
|
8995
|
+
const params = new URLSearchParams(window.location.search);
|
|
8996
|
+
activeSessionId = params.get(ANNOTATION_SESSION_PARAM);
|
|
8997
|
+
activeAnnotationId = params.get(ANNOTATION_ENTRY_PARAM);
|
|
8998
|
+
setAnnotationPanelOpen(params.get(ANNOTATION_PANEL_PARAM) === "open" || !!activeAnnotationId);
|
|
8903
8999
|
renderAnnotationPanel();
|
|
9000
|
+
restoreAnnotationDetailFromState();
|
|
8904
9001
|
applyInlineAnnotations();
|
|
8905
9002
|
}
|
|
8906
9003
|
async function waitForAnnotationDiffTarget(entry) {
|
|
@@ -9005,9 +9102,8 @@ ${frontmatter.yaml}
|
|
|
9005
9102
|
syncSessionUrl();
|
|
9006
9103
|
}
|
|
9007
9104
|
renderAnnotationPanel();
|
|
9105
|
+
restoreAnnotationDetailFromState();
|
|
9008
9106
|
applyInlineAnnotations();
|
|
9009
|
-
if (activeAnnotationId && !findAnnotation(activeAnnotationId))
|
|
9010
|
-
hideAnnotationDetail();
|
|
9011
9107
|
notifyAnnotationsChanged();
|
|
9012
9108
|
}
|
|
9013
9109
|
async function postAnnotationAction(payload) {
|
|
@@ -9167,6 +9263,10 @@ ${frontmatter.yaml}
|
|
|
9167
9263
|
time.className = "annotation-session-time";
|
|
9168
9264
|
time.textContent = annotationTimeLabel(session.created_at);
|
|
9169
9265
|
time.title = session.created_at;
|
|
9266
|
+
const count = document.createElement("span");
|
|
9267
|
+
count.className = "annotation-session-count";
|
|
9268
|
+
count.textContent = String(session.entries.length);
|
|
9269
|
+
count.title = `${session.entries.length} steps`;
|
|
9170
9270
|
title.addEventListener("click", () => {
|
|
9171
9271
|
setActiveSession(session.id === activeSessionId ? null : session.id);
|
|
9172
9272
|
});
|
|
@@ -9202,7 +9302,7 @@ ${frontmatter.yaml}
|
|
|
9202
9302
|
return;
|
|
9203
9303
|
postAnnotationAction({ action: "delete", id: session.id });
|
|
9204
9304
|
});
|
|
9205
|
-
head.append(title, time, rename, del);
|
|
9305
|
+
head.append(title, count, time, rename, del);
|
|
9206
9306
|
sessionEl.appendChild(head);
|
|
9207
9307
|
const list2 = document.createElement("ol");
|
|
9208
9308
|
list2.className = "annotation-entries";
|
|
@@ -9261,6 +9361,7 @@ ${frontmatter.yaml}
|
|
|
9261
9361
|
function hideAnnotationDetail() {
|
|
9262
9362
|
activeAnnotationId = null;
|
|
9263
9363
|
annotationDetail.hidden = true;
|
|
9364
|
+
syncSessionUrl();
|
|
9264
9365
|
updateActiveHighlights();
|
|
9265
9366
|
syncInlineAnnotationActive();
|
|
9266
9367
|
}
|
|
@@ -9304,6 +9405,25 @@ ${frontmatter.yaml}
|
|
|
9304
9405
|
updateActiveHighlights();
|
|
9305
9406
|
syncInlineAnnotationActive();
|
|
9306
9407
|
}
|
|
9408
|
+
function restoreAnnotationDetailFromState() {
|
|
9409
|
+
if (!activeAnnotationId) {
|
|
9410
|
+
annotationDetail.hidden = true;
|
|
9411
|
+
updateActiveHighlights();
|
|
9412
|
+
syncInlineAnnotationActive();
|
|
9413
|
+
return;
|
|
9414
|
+
}
|
|
9415
|
+
const found = findAnnotation(activeAnnotationId);
|
|
9416
|
+
if (!found) {
|
|
9417
|
+
activeAnnotationId = null;
|
|
9418
|
+
annotationDetail.hidden = true;
|
|
9419
|
+
syncSessionUrl();
|
|
9420
|
+
updateActiveHighlights();
|
|
9421
|
+
syncInlineAnnotationActive();
|
|
9422
|
+
return;
|
|
9423
|
+
}
|
|
9424
|
+
activeSessionId = found.session.id;
|
|
9425
|
+
showAnnotationDetail(found.session, found.entry, found.index);
|
|
9426
|
+
}
|
|
9307
9427
|
function focusStandaloneSourceLines(card, entry) {
|
|
9308
9428
|
if (!entry.line)
|
|
9309
9429
|
return;
|
|
@@ -9503,7 +9623,7 @@ ${frontmatter.yaml}
|
|
|
9503
9623
|
if (persist)
|
|
9504
9624
|
deps.setAnnotationPanelWidth(clamped);
|
|
9505
9625
|
}
|
|
9506
|
-
if (deps.getAnnotationPanelOpen())
|
|
9626
|
+
if (initialUrlParams.get(ANNOTATION_PANEL_PARAM) === "open" || activeAnnotationId || deps.getAnnotationPanelOpen())
|
|
9507
9627
|
setAnnotationPanelOpen(true);
|
|
9508
9628
|
applyAnnotationPanelWidth(deps.getAnnotationPanelWidth() ?? ANNOTATION_PANEL_DEFAULT_WIDTH, false);
|
|
9509
9629
|
updateDatabaseCaptureButton();
|
|
@@ -9784,6 +9904,9 @@ ${frontmatter.yaml}
|
|
|
9784
9904
|
name.appendChild(deps.createFileBreadcrumb(target.path, target.ref));
|
|
9785
9905
|
name.appendChild(createFilePathCopyButton(target));
|
|
9786
9906
|
header.appendChild(name);
|
|
9907
|
+
const repositoryWebLink = deps.createRepositoryWebLink?.(target);
|
|
9908
|
+
if (repositoryWebLink)
|
|
9909
|
+
header.appendChild(repositoryWebLink);
|
|
9787
9910
|
sticky.appendChild(header);
|
|
9788
9911
|
const tabsHost = document.createElement("div");
|
|
9789
9912
|
tabsHost.className = "gdp-file-detail-tabs";
|
|
@@ -9791,14 +9914,18 @@ ${frontmatter.yaml}
|
|
|
9791
9914
|
sticky.appendChild(tabsHost);
|
|
9792
9915
|
return { sticky, header, tabsHost };
|
|
9793
9916
|
}
|
|
9794
|
-
function mountFileShellCard(deps, target, card, repoTarget = deps.repoFileTargetFromRoute()) {
|
|
9917
|
+
function mountFileShellCard(deps, target, card, repoTarget = deps.repoFileTargetFromRoute(), options = {}) {
|
|
9795
9918
|
const root = deps.$("#diff");
|
|
9796
9919
|
if (repoTarget) {
|
|
9797
9920
|
const layout = document.createElement("div");
|
|
9798
9921
|
layout.className = "gdp-repo-blob-layout";
|
|
9799
9922
|
layout.appendChild(card);
|
|
9800
9923
|
root.prepend(layout);
|
|
9801
|
-
|
|
9924
|
+
if (options.loadSidebar !== false) {
|
|
9925
|
+
Promise.resolve(deps.renderRepoBlobSidebar(target.path, repoTarget)).catch((error2) => {
|
|
9926
|
+
console.error("[code-viewer] failed to load repository sidebar", error2);
|
|
9927
|
+
}).finally(() => deps.placeSidebarToggle());
|
|
9928
|
+
}
|
|
9802
9929
|
} else {
|
|
9803
9930
|
root.prepend(card);
|
|
9804
9931
|
}
|
|
@@ -9982,7 +10109,8 @@ ${frontmatter.yaml}
|
|
|
9982
10109
|
currentRange: deps.currentRange,
|
|
9983
10110
|
setRoute: deps.setRoute,
|
|
9984
10111
|
setPreferredSourceTab: deps.setPreferredSourceTab,
|
|
9985
|
-
createFileBreadcrumb: deps.createFileBreadcrumb
|
|
10112
|
+
createFileBreadcrumb: deps.createFileBreadcrumb,
|
|
10113
|
+
createRepositoryWebLink: deps.createRepositoryWebLink
|
|
9986
10114
|
}, target, "blame");
|
|
9987
10115
|
sticky.appendChild(buildLegend());
|
|
9988
10116
|
wrapper.appendChild(sticky);
|
|
@@ -9992,10 +10120,11 @@ ${frontmatter.yaml}
|
|
|
9992
10120
|
wrapper.appendChild(body);
|
|
9993
10121
|
card.appendChild(wrapper);
|
|
9994
10122
|
mountFileShellCard(deps, target, card);
|
|
10123
|
+
const sourceShikiLang = normalizeSourceShikiLang(deps.inferLang(target.path));
|
|
9995
10124
|
const [blameResp, srcText, highlighter] = await Promise.all([
|
|
9996
10125
|
fetchBlame(target, generation),
|
|
9997
10126
|
fetchSource(target, base2),
|
|
9998
|
-
deps.getSyntaxHighlight() ? deps.loadSourceShikiHighlighter() : Promise.resolve(null)
|
|
10127
|
+
deps.getSyntaxHighlight() && sourceShikiLang ? deps.loadSourceShikiHighlighter(sourceShikiLang) : Promise.resolve(null)
|
|
9999
10128
|
]);
|
|
10000
10129
|
if (generation !== activeGeneration)
|
|
10001
10130
|
return;
|
|
@@ -17925,6 +18054,23 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
17925
18054
|
spacer.className = "db-grid-spacer";
|
|
17926
18055
|
const body = document.createElement("div");
|
|
17927
18056
|
body.className = "db-grid-body";
|
|
18057
|
+
body.addEventListener("mouseover", (e2) => {
|
|
18058
|
+
const cell = e2.target?.closest(".db-grid-cell");
|
|
18059
|
+
if (!cell || !body.contains(cell))
|
|
18060
|
+
return;
|
|
18061
|
+
if (cell.dataset.gridTooltip) {
|
|
18062
|
+
delete cell.dataset.gridTooltip;
|
|
18063
|
+
cell.removeAttribute("title");
|
|
18064
|
+
}
|
|
18065
|
+
if (cell.title)
|
|
18066
|
+
return;
|
|
18067
|
+
if (cell.querySelector("input, textarea, select"))
|
|
18068
|
+
return;
|
|
18069
|
+
if (cell.scrollWidth > cell.clientWidth + 1) {
|
|
18070
|
+
cell.title = cell.textContent ?? "";
|
|
18071
|
+
cell.dataset.gridTooltip = "1";
|
|
18072
|
+
}
|
|
18073
|
+
});
|
|
17928
18074
|
const filteredEmpty = document.createElement("div");
|
|
17929
18075
|
filteredEmpty.className = "db-pane-empty";
|
|
17930
18076
|
filteredEmpty.hidden = true;
|
|
@@ -18113,8 +18259,23 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
18113
18259
|
}
|
|
18114
18260
|
}
|
|
18115
18261
|
}
|
|
18262
|
+
function defaultColWidth(colName) {
|
|
18263
|
+
const type = (columns.find((c2) => c2.name === colName)?.type ?? "").toLowerCase();
|
|
18264
|
+
let w = DEFAULT_COL_WIDTH;
|
|
18265
|
+
if (/timestamp|datetime/.test(type))
|
|
18266
|
+
w = 210;
|
|
18267
|
+
else if (/^(date|time|year)/.test(type))
|
|
18268
|
+
w = 120;
|
|
18269
|
+
else if (/bool|tinyint\(1\)/.test(type))
|
|
18270
|
+
w = 80;
|
|
18271
|
+
else if (/int|decimal|numeric|float|double|real/.test(type))
|
|
18272
|
+
w = 110;
|
|
18273
|
+
else if (/text|json|xml|blob/.test(type))
|
|
18274
|
+
w = 260;
|
|
18275
|
+
return Math.max(w, Math.min(240, colName.length * 7.5 + 34));
|
|
18276
|
+
}
|
|
18116
18277
|
function getColWidth(colName) {
|
|
18117
|
-
return colWidths.get(colName) ??
|
|
18278
|
+
return colWidths.get(colName) ?? defaultColWidth(colName);
|
|
18118
18279
|
}
|
|
18119
18280
|
function applyColWidth(colName, index) {
|
|
18120
18281
|
const w = getColWidth(colName);
|
|
@@ -22411,7 +22572,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22411
22572
|
});
|
|
22412
22573
|
chip.addEventListener("dragend", () => clearDragState());
|
|
22413
22574
|
}
|
|
22414
|
-
|
|
22575
|
+
tabsBar.addEventListener("dragover", (e2) => {
|
|
22415
22576
|
if (!draggingTabId)
|
|
22416
22577
|
return;
|
|
22417
22578
|
const target = e2.target?.closest(".db-tabs-chip");
|
|
@@ -22422,7 +22583,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22422
22583
|
e2.dataTransfer.dropEffect = "move";
|
|
22423
22584
|
clearDropTarget();
|
|
22424
22585
|
});
|
|
22425
|
-
|
|
22586
|
+
tabsBar.addEventListener("drop", (e2) => {
|
|
22426
22587
|
if (!draggingTabId)
|
|
22427
22588
|
return;
|
|
22428
22589
|
const target = e2.target?.closest(".db-tabs-chip");
|
|
@@ -23066,7 +23227,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23066
23227
|
if (!el)
|
|
23067
23228
|
return;
|
|
23068
23229
|
el.hidden = !branch;
|
|
23069
|
-
|
|
23230
|
+
const name = el.querySelector(".project-branch-name");
|
|
23231
|
+
if (name)
|
|
23232
|
+
name.textContent = branch;
|
|
23070
23233
|
el.title = branch ? `Current branch: ${branch}` : "";
|
|
23071
23234
|
}
|
|
23072
23235
|
let metaFilesForViewedProgress = [];
|
|
@@ -23773,7 +23936,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23773
23936
|
if (fresh && card.isConnected)
|
|
23774
23937
|
enqueueLoad(fresh, card, 0);
|
|
23775
23938
|
};
|
|
23776
|
-
|
|
23939
|
+
const request = trackLoad(fetch(url).then(async (r2) => {
|
|
23777
23940
|
if (!r2.ok)
|
|
23778
23941
|
throw new Error(await r2.text());
|
|
23779
23942
|
return r2.json();
|
|
@@ -23793,9 +23956,10 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23793
23956
|
if (String(myReq) !== card.dataset.reqId)
|
|
23794
23957
|
return;
|
|
23795
23958
|
renderFile(file, data, card);
|
|
23796
|
-
}).catch(() => {
|
|
23959
|
+
}).catch((error2) => {
|
|
23797
23960
|
if (String(myReq) !== card.dataset.reqId)
|
|
23798
23961
|
return;
|
|
23962
|
+
console.error("[code-viewer] failed to load diff", error2);
|
|
23799
23963
|
card.classList.remove("loading");
|
|
23800
23964
|
card.classList.add("error");
|
|
23801
23965
|
card.style.minHeight = "";
|
|
@@ -23812,13 +23976,24 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23812
23976
|
enqueueLoad(file, card, 1);
|
|
23813
23977
|
});
|
|
23814
23978
|
});
|
|
23979
|
+
const completed = request.finally(() => {
|
|
23980
|
+
if (card._loadPromise === completed)
|
|
23981
|
+
delete card._loadPromise;
|
|
23982
|
+
});
|
|
23983
|
+
card._loadPromise = completed;
|
|
23984
|
+
return completed;
|
|
23815
23985
|
}
|
|
23816
23986
|
async function loadDiffFile(path) {
|
|
23817
|
-
const
|
|
23987
|
+
const root = getDiffRoot?.() || document;
|
|
23988
|
+
const card = root.querySelector(diffCardSelector(path));
|
|
23818
23989
|
if (!card || card.classList.contains("gdp-standalone-source"))
|
|
23819
23990
|
return false;
|
|
23820
23991
|
if (card.classList.contains("loaded"))
|
|
23821
23992
|
return true;
|
|
23993
|
+
if (card.classList.contains("loading") && card._loadPromise) {
|
|
23994
|
+
await card._loadPromise;
|
|
23995
|
+
return card.classList.contains("loaded");
|
|
23996
|
+
}
|
|
23822
23997
|
const file = card._file || STATE.files.find((x) => x.path === path);
|
|
23823
23998
|
if (!file)
|
|
23824
23999
|
return false;
|
|
@@ -23874,9 +24049,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
23874
24049
|
const unfold = card.querySelector(".gdp-file-unfold");
|
|
23875
24050
|
if (unfold)
|
|
23876
24051
|
unfold.disabled = collapsed;
|
|
23877
|
-
|
|
23878
|
-
|
|
23879
|
-
|
|
24052
|
+
card.querySelectorAll(".gdp-preview-file, .gdp-view-file").forEach((button2) => {
|
|
24053
|
+
button2.disabled = collapsed;
|
|
24054
|
+
});
|
|
23880
24055
|
}
|
|
23881
24056
|
function setViewFileButtonState(button, sourceMode) {
|
|
23882
24057
|
if (!button)
|
|
@@ -24076,6 +24251,27 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
24076
24251
|
wrap.appendChild(box);
|
|
24077
24252
|
}
|
|
24078
24253
|
header.appendChild(wrap);
|
|
24254
|
+
if (!header.querySelector(".gdp-preview-file") && isPreviewableSource(fileSourceTarget(file).path)) {
|
|
24255
|
+
const previewFile = document.createElement("button");
|
|
24256
|
+
previewFile.type = "button";
|
|
24257
|
+
previewFile.className = "gdp-preview-file gdp-btn gdp-btn-sm";
|
|
24258
|
+
previewFile.textContent = "Preview";
|
|
24259
|
+
previewFile.title = "Preview rendered file";
|
|
24260
|
+
previewFile.addEventListener("click", (e2) => {
|
|
24261
|
+
e2.stopPropagation();
|
|
24262
|
+
const target = fileSourceTarget(file);
|
|
24263
|
+
setRoute({
|
|
24264
|
+
screen: "file",
|
|
24265
|
+
path: target.path,
|
|
24266
|
+
ref: target.ref,
|
|
24267
|
+
view: "blob",
|
|
24268
|
+
preview: true,
|
|
24269
|
+
range: currentRange()
|
|
24270
|
+
});
|
|
24271
|
+
applySourceRouteToShell();
|
|
24272
|
+
});
|
|
24273
|
+
header.appendChild(previewFile);
|
|
24274
|
+
}
|
|
24079
24275
|
if (!header.querySelector(".gdp-view-file")) {
|
|
24080
24276
|
const viewFile = document.createElement("button");
|
|
24081
24277
|
viewFile.type = "button";
|
|
@@ -25609,7 +25805,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25609
25805
|
(el.closest(".gdp-repo-blob-layout") || el).remove();
|
|
25610
25806
|
});
|
|
25611
25807
|
}
|
|
25612
|
-
function renderFileHistoryShell(deps, route) {
|
|
25808
|
+
function renderFileHistoryShell(deps, route, options = {}) {
|
|
25613
25809
|
removeFileHistoryShell();
|
|
25614
25810
|
const target = { path: route.path, ref: route.ref };
|
|
25615
25811
|
const card = document.createElement("article");
|
|
@@ -25645,7 +25841,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25645
25841
|
body.appendChild(embed);
|
|
25646
25842
|
wrapper.appendChild(body);
|
|
25647
25843
|
card.appendChild(wrapper);
|
|
25648
|
-
mountFileShellCard(deps, target, card, target.ref);
|
|
25844
|
+
mountFileShellCard(deps, target, card, target.ref, options);
|
|
25649
25845
|
return {
|
|
25650
25846
|
...panelDom,
|
|
25651
25847
|
commitInfo,
|
|
@@ -26054,6 +26250,10 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26054
26250
|
kind: "paragraph",
|
|
26055
26251
|
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."
|
|
26056
26252
|
},
|
|
26253
|
+
{
|
|
26254
|
+
kind: "paragraph",
|
|
26255
|
+
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."
|
|
26256
|
+
},
|
|
26057
26257
|
{
|
|
26058
26258
|
kind: "paragraph",
|
|
26059
26259
|
text: "In large repositories the sidebar loads folder children on demand. Folders you open are remembered and automatically re-expanded after a reload."
|
|
@@ -26145,6 +26345,10 @@ code-viewer doctor --bin git=/opt/bin/git --bin docker=/opt/bin/docker --bin gh=
|
|
|
26145
26345
|
kind: "paragraph",
|
|
26146
26346
|
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."
|
|
26147
26347
|
},
|
|
26348
|
+
{
|
|
26349
|
+
kind: "paragraph",
|
|
26350
|
+
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."
|
|
26351
|
+
},
|
|
26148
26352
|
{
|
|
26149
26353
|
kind: "paragraph",
|
|
26150
26354
|
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)."
|
|
@@ -26253,6 +26457,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
26253
26457
|
[
|
|
26254
26458
|
"Persistent state",
|
|
26255
26459
|
"Open/closed, width, follow, mute, and rate are stored under .code-viewer/settings.json; annotations themselves live in .code-viewer/annotations.json."
|
|
26460
|
+
],
|
|
26461
|
+
[
|
|
26462
|
+
"Restorable URL",
|
|
26463
|
+
"The panel-open state, selected session, and selected annotation are kept in the URL, so reloads and shared links restore the same walkthrough context."
|
|
26256
26464
|
]
|
|
26257
26465
|
]
|
|
26258
26466
|
}
|
|
@@ -26725,6 +26933,10 @@ code-viewer query agent-help`
|
|
|
26725
26933
|
kind: "paragraph",
|
|
26726
26934
|
text: "ファイル詳細ページには最大 4 つのタブ (Preview / Code / Blame / History) があります。テキストファイルは Code がデフォルトで、?preview=1 を付けると Markdown / HTML プレビューに切り替わります。画像・動画・音声・PDF などのメディアファイルは Preview タブのみ表示され、Code タブは表示されません。Blame と History はそれぞれ専用 URL (view=blame, view=history) を持つため、ディープリンクとブラウザの戻る / 進むが同期し、いずれも Repository サイドバーは表示されたままです。"
|
|
26727
26935
|
},
|
|
26936
|
+
{
|
|
26937
|
+
kind: "paragraph",
|
|
26938
|
+
text: "リポジトリの remote が GitHub の場合、リポジトリとファイルのヘッダーから現在のパスを GitHub で開けます。ソース行を選択すると、AI 参照のコピー、選択行範囲を GitHub で開く、GitHub URL のコピーを個別に選べます。Markdown / HTML の diff カードには直接 Preview を開く導線も表示されます。"
|
|
26939
|
+
},
|
|
26728
26940
|
{
|
|
26729
26941
|
kind: "paragraph",
|
|
26730
26942
|
text: "大きいリポジトリではサイドバーがフォルダの中身を必要に応じて読み込みます。開いたフォルダは記憶され、次回のリロード時に同じ状態で展開し直されます。"
|
|
@@ -26816,6 +27028,10 @@ code-viewer doctor --bin git=/opt/bin/git --bin docker=/opt/bin/docker --bin gh=
|
|
|
26816
27028
|
kind: "paragraph",
|
|
26817
27029
|
text: ".code-viewer/ の中身はすべて code-viewer が管理します。JSON ファイルは書き込みごとにバリデーションを通して安全に書き換えられるため、未知のキーは破棄され、不正な値は既定値に戻されます。手で編集すると壊れる可能性があり、壊れたファイルは .corrupt サフィックスに改名されて空の既定値で置き換えられます。"
|
|
26818
27030
|
},
|
|
27031
|
+
{
|
|
27032
|
+
kind: "paragraph",
|
|
27033
|
+
text: "ディレクトリはリポジトリツリーに表示され、テキストファイルは Code ビューで確認できます。リポジトリ検索と diff の対象からは引き続き除外されます。"
|
|
27034
|
+
},
|
|
26819
27035
|
{
|
|
26820
27036
|
kind: "paragraph",
|
|
26821
27037
|
text: "ディレクトリごと削除するのが、このリポジトリの全状態をリセットする推奨手順です。個別ファイルだけを消した場合はその系統だけがリセットされます(例: tabs.json を消すと次回起動時に DB タブがすべて閉じた状態になります)。"
|
|
@@ -26924,6 +27140,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
26924
27140
|
[
|
|
26925
27141
|
"永続化",
|
|
26926
27142
|
"パネルの開閉・幅・follow・ミュート・速度は .code-viewer/settings.json に、注釈自体は .code-viewer/annotations.json に保存されます。"
|
|
27143
|
+
],
|
|
27144
|
+
[
|
|
27145
|
+
"復元できる URL",
|
|
27146
|
+
"パネルの開閉、選択中のセッション、選択中の注釈は URL に反映されるため、リロードや共有リンクでも同じウォークスルー状態を復元できます。"
|
|
26927
27147
|
]
|
|
26928
27148
|
]
|
|
26929
27149
|
}
|
|
@@ -28206,7 +28426,7 @@ code-viewer query agent-help`
|
|
|
28206
28426
|
let mounted = false;
|
|
28207
28427
|
let lifecycle = 0;
|
|
28208
28428
|
let data = null;
|
|
28209
|
-
let activeTab = "
|
|
28429
|
+
let activeTab = "tasks";
|
|
28210
28430
|
let selectedDate = todayIsoDate();
|
|
28211
28431
|
let selectedEntryId = "";
|
|
28212
28432
|
let creatingEntry = false;
|
|
@@ -28379,7 +28599,7 @@ code-viewer query agent-help`
|
|
|
28379
28599
|
function applyRoute(route = deps.getRoute()) {
|
|
28380
28600
|
if (!isJournalRoute(route))
|
|
28381
28601
|
return;
|
|
28382
|
-
activeTab = route.tab || activeTab || "
|
|
28602
|
+
activeTab = route.tab || activeTab || "tasks";
|
|
28383
28603
|
selectedDate = route.date || selectedDate || todayIsoDate();
|
|
28384
28604
|
labelFilter = route.label || "";
|
|
28385
28605
|
selectedTaskId = route.task || "";
|
|
@@ -29942,21 +30162,50 @@ code-viewer query agent-help`
|
|
|
29942
30162
|
const copyButton = document.createElement("button");
|
|
29943
30163
|
copyButton.id = "line-ref-pill-copy";
|
|
29944
30164
|
copyButton.type = "button";
|
|
29945
|
-
copyButton.title = "選択行の参照をコピー(Claude Code / Codex に貼り付け用)。Shift+Click でコード本体も添付。";
|
|
29946
30165
|
const closeButton = document.createElement("button");
|
|
29947
30166
|
closeButton.id = "line-ref-pill-close";
|
|
29948
30167
|
closeButton.type = "button";
|
|
29949
30168
|
closeButton.title = "選択を解除";
|
|
29950
30169
|
closeButton.setAttribute("aria-label", "選択を解除");
|
|
29951
30170
|
closeButton.textContent = "×";
|
|
29952
|
-
|
|
29953
|
-
pill
|
|
30171
|
+
const githubActions = document.createElement("div");
|
|
30172
|
+
githubActions.id = "line-ref-pill-github-actions";
|
|
30173
|
+
githubActions.hidden = true;
|
|
30174
|
+
const githubOpen = document.createElement("a");
|
|
30175
|
+
githubOpen.id = "line-ref-pill-github-open";
|
|
30176
|
+
githubOpen.target = "_blank";
|
|
30177
|
+
githubOpen.rel = "noopener";
|
|
30178
|
+
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);
|
|
30179
|
+
const githubCopy = document.createElement("button");
|
|
30180
|
+
githubCopy.id = "line-ref-pill-github-copy";
|
|
30181
|
+
githubCopy.type = "button";
|
|
30182
|
+
githubCopy.innerHTML = `<span class="lrp-github-copy-icon">${iconSvg("octicon-copy", COPY_16_PATHS)}</span>` + '<span class="lrp-github-copy-label"></span>';
|
|
30183
|
+
githubActions.append(githubOpen, githubCopy);
|
|
30184
|
+
pill.append(copyButton, githubActions, closeButton);
|
|
29954
30185
|
document.body.appendChild(pill);
|
|
29955
30186
|
let refText = "";
|
|
29956
30187
|
let currentPath = "";
|
|
29957
30188
|
let currentStart = 0;
|
|
29958
30189
|
let currentEnd = 0;
|
|
30190
|
+
let githubUrl = "";
|
|
29959
30191
|
let feedbackTimer = null;
|
|
30192
|
+
let githubFeedbackTimer = null;
|
|
30193
|
+
function renderGithubActions() {
|
|
30194
|
+
const openTitle = deps.githubOpenTitle();
|
|
30195
|
+
const copyTitle = deps.githubCopyTitle();
|
|
30196
|
+
githubOpen.title = openTitle;
|
|
30197
|
+
githubOpen.setAttribute("aria-label", openTitle);
|
|
30198
|
+
githubCopy.title = copyTitle;
|
|
30199
|
+
githubCopy.setAttribute("aria-label", copyTitle);
|
|
30200
|
+
const openLabel = githubOpen.querySelector(".lrp-github-open-label");
|
|
30201
|
+
if (openLabel)
|
|
30202
|
+
openLabel.textContent = openTitle;
|
|
30203
|
+
const copyLabel = githubCopy.querySelector(".lrp-github-copy-label");
|
|
30204
|
+
if (copyLabel)
|
|
30205
|
+
copyLabel.textContent = copyTitle;
|
|
30206
|
+
githubOpen.href = githubUrl || "#";
|
|
30207
|
+
githubActions.hidden = !githubUrl;
|
|
30208
|
+
}
|
|
29960
30209
|
function selectionLineCount() {
|
|
29961
30210
|
return currentEnd - currentStart + 1;
|
|
29962
30211
|
}
|
|
@@ -29965,25 +30214,16 @@ code-viewer query agent-help`
|
|
|
29965
30214
|
if (count <= 1)
|
|
29966
30215
|
return "";
|
|
29967
30216
|
const warn = count >= AI_CONTEXT_LARGE_SELECTION_LINE_THRESHOLD;
|
|
29968
|
-
return `<span class="lrp-count${warn ? " lrp-count-warn" : ""}">${count}
|
|
30217
|
+
return `<span class="lrp-count${warn ? " lrp-count-warn" : ""}">${escapeHtml2(deps.lineCountLabel(count))}</span>`;
|
|
29969
30218
|
}
|
|
29970
30219
|
function render(state) {
|
|
29971
|
-
|
|
29972
|
-
|
|
29973
|
-
|
|
29974
|
-
|
|
29975
|
-
}
|
|
29976
|
-
|
|
29977
|
-
|
|
29978
|
-
const suffix = count > 1 ? ` (${count} lines)` : "";
|
|
29979
|
-
copyButton.innerHTML = `${CHECK_ICON}<span class="lrp-label">Copied + code${suffix}</span>`;
|
|
29980
|
-
return;
|
|
29981
|
-
}
|
|
29982
|
-
if (state === "failed") {
|
|
29983
|
-
copyButton.innerHTML = `${COPY_ICON}<span class="lrp-label">copy failed</span>`;
|
|
29984
|
-
return;
|
|
29985
|
-
}
|
|
29986
|
-
copyButton.innerHTML = `${COPY_ICON}<span class="lrp-label">Copy</span>` + `<span class="lrp-ref">${escapeHtml2(refText)}</span>` + countBadgeHtml();
|
|
30220
|
+
copyButton.classList.toggle("copied", state === "copied" || state === "copied-code");
|
|
30221
|
+
copyButton.classList.toggle("failed", state === "failed");
|
|
30222
|
+
const icon = state === "copied" || state === "copied-code" ? CHECK_ICON : COPY_ICON;
|
|
30223
|
+
const label = deps.copyReferenceLabel();
|
|
30224
|
+
copyButton.innerHTML = `${icon}<span class="lrp-label">${escapeHtml2(label)}</span>` + `<span class="lrp-ref">${escapeHtml2(refText)}</span>` + countBadgeHtml();
|
|
30225
|
+
copyButton.title = label;
|
|
30226
|
+
copyButton.setAttribute("aria-label", label);
|
|
29987
30227
|
}
|
|
29988
30228
|
copyButton.addEventListener("click", async (event) => {
|
|
29989
30229
|
if (!refText)
|
|
@@ -30012,6 +30252,28 @@ code-viewer query agent-help`
|
|
|
30012
30252
|
render("ready");
|
|
30013
30253
|
}, 1200);
|
|
30014
30254
|
});
|
|
30255
|
+
githubCopy.addEventListener("click", async () => {
|
|
30256
|
+
if (!githubUrl)
|
|
30257
|
+
return;
|
|
30258
|
+
try {
|
|
30259
|
+
await navigator.clipboard.writeText(githubUrl);
|
|
30260
|
+
githubCopy.classList.add("copied");
|
|
30261
|
+
const icon = githubCopy.querySelector(".lrp-github-copy-icon");
|
|
30262
|
+
if (icon)
|
|
30263
|
+
icon.innerHTML = CHECK_ICON;
|
|
30264
|
+
} catch {
|
|
30265
|
+
githubCopy.classList.add("failed");
|
|
30266
|
+
}
|
|
30267
|
+
if (githubFeedbackTimer)
|
|
30268
|
+
clearTimeout(githubFeedbackTimer);
|
|
30269
|
+
githubFeedbackTimer = setTimeout(() => {
|
|
30270
|
+
githubFeedbackTimer = null;
|
|
30271
|
+
githubCopy.classList.remove("copied", "failed");
|
|
30272
|
+
const icon = githubCopy.querySelector(".lrp-github-copy-icon");
|
|
30273
|
+
if (icon)
|
|
30274
|
+
icon.innerHTML = iconSvg("octicon-copy", COPY_16_PATHS);
|
|
30275
|
+
}, 1200);
|
|
30276
|
+
});
|
|
30015
30277
|
closeButton.addEventListener("click", () => {
|
|
30016
30278
|
deps.onClose();
|
|
30017
30279
|
});
|
|
@@ -30025,6 +30287,8 @@ code-viewer query agent-help`
|
|
|
30025
30287
|
currentPath = path;
|
|
30026
30288
|
currentStart = Math.max(1, Math.floor(Math.min(start, end)));
|
|
30027
30289
|
currentEnd = Math.max(1, Math.floor(Math.max(start, end)));
|
|
30290
|
+
githubUrl = deps.githubUrlForSelection(currentPath, currentStart, currentEnd) || "";
|
|
30291
|
+
renderGithubActions();
|
|
30028
30292
|
if (feedbackTimer) {
|
|
30029
30293
|
clearTimeout(feedbackTimer);
|
|
30030
30294
|
feedbackTimer = null;
|
|
@@ -30042,6 +30306,8 @@ code-viewer query agent-help`
|
|
|
30042
30306
|
currentPath = "";
|
|
30043
30307
|
currentStart = 0;
|
|
30044
30308
|
currentEnd = 0;
|
|
30309
|
+
githubUrl = "";
|
|
30310
|
+
githubActions.hidden = true;
|
|
30045
30311
|
pill.hidden = true;
|
|
30046
30312
|
}
|
|
30047
30313
|
};
|
|
@@ -30161,14 +30427,34 @@ code-viewer query agent-help`
|
|
|
30161
30427
|
if (!popBody || !popSearch)
|
|
30162
30428
|
return;
|
|
30163
30429
|
let popTarget = null;
|
|
30430
|
+
let refsLoaded = false;
|
|
30431
|
+
let refsLoading = false;
|
|
30432
|
+
let refsError = false;
|
|
30433
|
+
let refsInFlight = null;
|
|
30164
30434
|
function fetchRefs() {
|
|
30165
|
-
|
|
30435
|
+
if (refsLoaded)
|
|
30436
|
+
return Promise.resolve();
|
|
30437
|
+
if (refsInFlight)
|
|
30438
|
+
return refsInFlight;
|
|
30439
|
+
refsLoading = true;
|
|
30440
|
+
refsError = false;
|
|
30441
|
+
const request = fetch("/_refs").then((r2) => r2.json()).then((refs) => {
|
|
30166
30442
|
Object.assign(REFS, refs);
|
|
30167
|
-
|
|
30168
|
-
|
|
30443
|
+
refsLoaded = true;
|
|
30444
|
+
if (!popover.hidden && popTab !== "commits")
|
|
30445
|
+
buildPopBody(popSearch.value);
|
|
30446
|
+
}).catch((error2) => {
|
|
30447
|
+
refsError = true;
|
|
30448
|
+
console.error("[code-viewer] failed to load refs", error2);
|
|
30449
|
+
}).finally(() => {
|
|
30450
|
+
refsLoading = false;
|
|
30451
|
+
refsInFlight = null;
|
|
30452
|
+
if (!popover.hidden && popTab !== "commits")
|
|
30453
|
+
buildPopBody(popSearch.value);
|
|
30169
30454
|
});
|
|
30455
|
+
refsInFlight = request;
|
|
30456
|
+
return request;
|
|
30170
30457
|
}
|
|
30171
|
-
fetchRefs();
|
|
30172
30458
|
let popTab = "commits";
|
|
30173
30459
|
const COMMIT_PAGE_SIZE = 50;
|
|
30174
30460
|
let commitSearchTimer = null;
|
|
@@ -30309,6 +30595,10 @@ code-viewer query agent-help`
|
|
|
30309
30595
|
} else if (commitHasMore) {
|
|
30310
30596
|
html.push('<div class="rp-empty">scroll for more commits...</div>');
|
|
30311
30597
|
}
|
|
30598
|
+
} else if (refsLoading) {
|
|
30599
|
+
html.push('<div class="rp-empty">loading refs...</div>');
|
|
30600
|
+
} else if (refsError) {
|
|
30601
|
+
html.push('<div class="rp-empty">failed to load refs</div>');
|
|
30312
30602
|
} else if (popTab === "branches") {
|
|
30313
30603
|
const branches = (REFS.branches || []).filter((b2) => m(b2.name));
|
|
30314
30604
|
if (!branches.length) {
|
|
@@ -30443,6 +30733,14 @@ code-viewer query agent-help`
|
|
|
30443
30733
|
});
|
|
30444
30734
|
if (popTab === "commits")
|
|
30445
30735
|
scheduleCommitSearch(popSearch.value);
|
|
30736
|
+
else {
|
|
30737
|
+
if (commitSearchTimer) {
|
|
30738
|
+
clearTimeout(commitSearchTimer);
|
|
30739
|
+
commitSearchTimer = null;
|
|
30740
|
+
}
|
|
30741
|
+
commitSearchLoading = false;
|
|
30742
|
+
fetchRefs();
|
|
30743
|
+
}
|
|
30446
30744
|
buildPopBody(popSearch.value);
|
|
30447
30745
|
});
|
|
30448
30746
|
});
|
|
@@ -30479,6 +30777,19 @@ code-viewer query agent-help`
|
|
|
30479
30777
|
return trimmed;
|
|
30480
30778
|
}
|
|
30481
30779
|
|
|
30780
|
+
// web-src/views/repository-web-link.ts
|
|
30781
|
+
function createRepositoryWebLink(target, label) {
|
|
30782
|
+
const link2 = document.createElement("a");
|
|
30783
|
+
link2.className = "gdp-btn gdp-btn-sm gdp-repo-web-link";
|
|
30784
|
+
link2.href = target.url;
|
|
30785
|
+
link2.target = "_blank";
|
|
30786
|
+
link2.rel = "noopener";
|
|
30787
|
+
link2.title = label;
|
|
30788
|
+
link2.setAttribute("aria-label", label);
|
|
30789
|
+
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>`;
|
|
30790
|
+
return link2;
|
|
30791
|
+
}
|
|
30792
|
+
|
|
30482
30793
|
// web-src/core/file-filter.ts
|
|
30483
30794
|
function normalizeFileFilterQuery(value) {
|
|
30484
30795
|
return (value || "").toLowerCase().trim();
|
|
@@ -32190,6 +32501,9 @@ code-viewer query agent-help`
|
|
|
32190
32501
|
repositoryFallback,
|
|
32191
32502
|
repositoryRootFallback,
|
|
32192
32503
|
commitEntryMeta,
|
|
32504
|
+
repositoryWebTarget,
|
|
32505
|
+
openGithubLabel,
|
|
32506
|
+
openRepositoryWebLabel,
|
|
32193
32507
|
fileBadge
|
|
32194
32508
|
} = deps;
|
|
32195
32509
|
let REPO_SORT = {
|
|
@@ -32345,6 +32659,13 @@ code-viewer query agent-help`
|
|
|
32345
32659
|
});
|
|
32346
32660
|
return button;
|
|
32347
32661
|
}
|
|
32662
|
+
function createRepositoryWebLink2(path, ref) {
|
|
32663
|
+
const target = repositoryWebTarget(path, ref);
|
|
32664
|
+
if (!target)
|
|
32665
|
+
return null;
|
|
32666
|
+
const label = target.provider === "github" ? openGithubLabel() : openRepositoryWebLabel();
|
|
32667
|
+
return createRepositoryWebLink(target, label);
|
|
32668
|
+
}
|
|
32348
32669
|
function showRepoContextMenu(event, entry, ref, onChanged) {
|
|
32349
32670
|
if (document.querySelector(".gdp-dialog-backdrop"))
|
|
32350
32671
|
return false;
|
|
@@ -32582,6 +32903,9 @@ code-viewer query agent-help`
|
|
|
32582
32903
|
pathHeader.appendChild(createCopyPathButton(meta.path));
|
|
32583
32904
|
pathHeader.appendChild(createOpenPathButton(meta.path || "", "directory", openDirectoryInOsTitle()));
|
|
32584
32905
|
toolbar.appendChild(pathHeader);
|
|
32906
|
+
const repositoryWebLink = createRepositoryWebLink2(meta.path || "", meta.ref);
|
|
32907
|
+
if (repositoryWebLink)
|
|
32908
|
+
toolbar.appendChild(repositoryWebLink);
|
|
32585
32909
|
if (canTrashWorktreeRef(meta.ref)) {
|
|
32586
32910
|
toolbar.appendChild(createNewFolderButton(meta.path || "", () => loadRepo()));
|
|
32587
32911
|
if (meta.path) {
|
|
@@ -33935,6 +34259,7 @@ code-viewer query agent-help`
|
|
|
33935
34259
|
renderRepoBlobSidebar,
|
|
33936
34260
|
placeSidebarToggle,
|
|
33937
34261
|
createFileBreadcrumb,
|
|
34262
|
+
createRepositoryWebLink: createRepositoryWebLink2,
|
|
33938
34263
|
createFileDetailMeta,
|
|
33939
34264
|
createOpenPathButton,
|
|
33940
34265
|
createMoveToTrashButton,
|
|
@@ -33953,7 +34278,6 @@ code-viewer query agent-help`
|
|
|
33953
34278
|
const VIRTUAL_SOURCE_HIGHLIGHT_MAX_LINE_LENGTH = 2000;
|
|
33954
34279
|
const UNKNOWN_TEXT_SNIFF_BYTES = 8192;
|
|
33955
34280
|
const SOURCE_LOADING_SLOW_THRESHOLD_MS = 3000;
|
|
33956
|
-
let sourceShikiLoadPromise = null;
|
|
33957
34281
|
let PREFERRED_SOURCE_TAB = null;
|
|
33958
34282
|
let SOURCE_CURSOR = null;
|
|
33959
34283
|
let SOURCE_CURSOR_ROWS = [];
|
|
@@ -33966,8 +34290,13 @@ code-viewer query agent-help`
|
|
|
33966
34290
|
if (sourceRow)
|
|
33967
34291
|
return sourceRow.getBoundingClientRect().height || 20;
|
|
33968
34292
|
const preview = document.querySelector("#content .gdp-markdown-preview:not([hidden])");
|
|
33969
|
-
|
|
33970
|
-
|
|
34293
|
+
if (preview) {
|
|
34294
|
+
const previewLineHeight = Number.parseFloat(getComputedStyle(preview).lineHeight);
|
|
34295
|
+
if (Number.isFinite(previewLineHeight) && previewLineHeight > 0)
|
|
34296
|
+
return previewLineHeight;
|
|
34297
|
+
}
|
|
34298
|
+
const configuredLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
34299
|
+
return Number.isFinite(configuredLineHeight) && configuredLineHeight > 0 ? configuredLineHeight : VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
33971
34300
|
}
|
|
33972
34301
|
function hasVisibleSourceCodeSurface() {
|
|
33973
34302
|
return Array.from(document.querySelectorAll("#content .gdp-source-virtual-scroller, #content .gdp-source-table")).some((item) => item.offsetParent !== null);
|
|
@@ -34008,8 +34337,9 @@ code-viewer query agent-help`
|
|
|
34008
34337
|
}
|
|
34009
34338
|
function visibleSourceLineFallback() {
|
|
34010
34339
|
const scroller = findMainScrollTarget();
|
|
34340
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
34011
34341
|
if (scroller)
|
|
34012
|
-
return Math.max(1, Math.floor(scroller.scrollTop /
|
|
34342
|
+
return Math.max(1, Math.floor(scroller.scrollTop / rowHeight) + 1);
|
|
34013
34343
|
const rows = $$("#content .gdp-source-table tr[data-line]");
|
|
34014
34344
|
const contentTop = document.querySelector("#content")?.getBoundingClientRect().top ?? 0;
|
|
34015
34345
|
const row = rows.find((item) => item.getBoundingClientRect().bottom >= Math.max(0, contentTop));
|
|
@@ -34033,8 +34363,9 @@ code-viewer query agent-help`
|
|
|
34033
34363
|
function scrollSourceCursorIntoView(cursor, edge = "nearest") {
|
|
34034
34364
|
const scroller = findMainScrollTarget();
|
|
34035
34365
|
if (scroller) {
|
|
34036
|
-
const
|
|
34037
|
-
const
|
|
34366
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
34367
|
+
const top = (cursor.line - 1) * rowHeight;
|
|
34368
|
+
const bottom = top + rowHeight;
|
|
34038
34369
|
const before = scroller.scrollTop;
|
|
34039
34370
|
if (edge === "center")
|
|
34040
34371
|
scroller.scrollTop = Math.max(0, top - Math.round(scroller.clientHeight / 2));
|
|
@@ -34127,86 +34458,13 @@ code-viewer query agent-help`
|
|
|
34127
34458
|
focusMainPanel();
|
|
34128
34459
|
return true;
|
|
34129
34460
|
}
|
|
34130
|
-
|
|
34131
|
-
|
|
34132
|
-
|
|
34133
|
-
|
|
34134
|
-
|
|
34135
|
-
|
|
34136
|
-
|
|
34137
|
-
"cmake",
|
|
34138
|
-
"cpp",
|
|
34139
|
-
"csharp",
|
|
34140
|
-
"css",
|
|
34141
|
-
"dart",
|
|
34142
|
-
"diff",
|
|
34143
|
-
"dockerfile",
|
|
34144
|
-
"dotenv",
|
|
34145
|
-
"elixir",
|
|
34146
|
-
"erb",
|
|
34147
|
-
"erlang",
|
|
34148
|
-
"fortran",
|
|
34149
|
-
"go",
|
|
34150
|
-
"gradle",
|
|
34151
|
-
"graphql",
|
|
34152
|
-
"haml",
|
|
34153
|
-
"handlebars",
|
|
34154
|
-
"haskell",
|
|
34155
|
-
"html",
|
|
34156
|
-
"ini",
|
|
34157
|
-
"java",
|
|
34158
|
-
"javascript",
|
|
34159
|
-
"json",
|
|
34160
|
-
"jsonc",
|
|
34161
|
-
"julia",
|
|
34162
|
-
"kotlin",
|
|
34163
|
-
"less",
|
|
34164
|
-
"liquid",
|
|
34165
|
-
"lua",
|
|
34166
|
-
"make",
|
|
34167
|
-
"markdown",
|
|
34168
|
-
"nix",
|
|
34169
|
-
"ocaml",
|
|
34170
|
-
"pascal",
|
|
34171
|
-
"perl",
|
|
34172
|
-
"php",
|
|
34173
|
-
"powershell",
|
|
34174
|
-
"prisma",
|
|
34175
|
-
"properties",
|
|
34176
|
-
"protobuf",
|
|
34177
|
-
"pug",
|
|
34178
|
-
"python",
|
|
34179
|
-
"r",
|
|
34180
|
-
"rst",
|
|
34181
|
-
"ruby",
|
|
34182
|
-
"rust",
|
|
34183
|
-
"sass",
|
|
34184
|
-
"scala",
|
|
34185
|
-
"scss",
|
|
34186
|
-
"sql",
|
|
34187
|
-
"swift",
|
|
34188
|
-
"terraform",
|
|
34189
|
-
"tex",
|
|
34190
|
-
"toml",
|
|
34191
|
-
"twig",
|
|
34192
|
-
"typescript",
|
|
34193
|
-
"vim",
|
|
34194
|
-
"vue",
|
|
34195
|
-
"xml",
|
|
34196
|
-
"yaml"
|
|
34197
|
-
]));
|
|
34198
|
-
function loadSourceShikiHighlighter() {
|
|
34199
|
-
if (!sourceShikiLoadPromise) {
|
|
34200
|
-
sourceShikiLoadPromise = import("/shiki.js").then((mod) => {
|
|
34201
|
-
const typed = mod;
|
|
34202
|
-
const langs = typed.bundledLanguages ? SOURCE_SHIKI_LANGS.filter((lang) => !!typed.bundledLanguages?.[lang]) : SOURCE_SHIKI_LANGS;
|
|
34203
|
-
return typed.createHighlighter({
|
|
34204
|
-
themes: ["github-light", "github-dark"],
|
|
34205
|
-
langs
|
|
34206
|
-
});
|
|
34207
|
-
}).catch(() => null);
|
|
34208
|
-
}
|
|
34209
|
-
return sourceShikiLoadPromise;
|
|
34461
|
+
function loadSourceShikiHighlighter(lang) {
|
|
34462
|
+
if (deps.loadSourceHighlighter)
|
|
34463
|
+
return deps.loadSourceHighlighter(lang);
|
|
34464
|
+
return loadShikiHighlighter({
|
|
34465
|
+
themes: ["github-light", "github-dark"],
|
|
34466
|
+
langs: [lang]
|
|
34467
|
+
});
|
|
34210
34468
|
}
|
|
34211
34469
|
function sourceShikiLines(textValue, lang, highlighter) {
|
|
34212
34470
|
try {
|
|
@@ -34225,6 +34483,57 @@ code-viewer query agent-help`
|
|
|
34225
34483
|
return null;
|
|
34226
34484
|
}
|
|
34227
34485
|
}
|
|
34486
|
+
function scheduleSourceHighlight(table2, target, textValue, lang, signal) {
|
|
34487
|
+
setTimeout(() => {
|
|
34488
|
+
if (signal?.aborted || !table2.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34489
|
+
return;
|
|
34490
|
+
loadSourceShikiHighlighter(lang).then((highlighter) => {
|
|
34491
|
+
if (!highlighter || signal?.aborted || !table2.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34492
|
+
return;
|
|
34493
|
+
const highlightedLines = sourceShikiLines(textValue, lang, highlighter);
|
|
34494
|
+
if (!highlightedLines || signal?.aborted || !table2.isConnected || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34495
|
+
return;
|
|
34496
|
+
const cells = table2.querySelectorAll(".gdp-source-line-code");
|
|
34497
|
+
cells.forEach((cell, index) => {
|
|
34498
|
+
if (highlightedLines[index] == null)
|
|
34499
|
+
return;
|
|
34500
|
+
cell.innerHTML = highlightedLines[index] || " ";
|
|
34501
|
+
cell.classList.add("shiki");
|
|
34502
|
+
});
|
|
34503
|
+
}).catch((err) => {
|
|
34504
|
+
console.error("Failed to apply source syntax highlighting", err);
|
|
34505
|
+
});
|
|
34506
|
+
}, 0);
|
|
34507
|
+
}
|
|
34508
|
+
function scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, onReplace) {
|
|
34509
|
+
setTimeout(() => {
|
|
34510
|
+
if (signal?.aborted || !preview.isConnected || !STATE.syntaxHighlight || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34511
|
+
return;
|
|
34512
|
+
(deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34513
|
+
syntaxHighlight: true,
|
|
34514
|
+
signal,
|
|
34515
|
+
onNavigateMarkdown: (path, ref) => {
|
|
34516
|
+
setRoute({
|
|
34517
|
+
screen: "file",
|
|
34518
|
+
path,
|
|
34519
|
+
ref,
|
|
34520
|
+
view: "blob",
|
|
34521
|
+
range: currentRange()
|
|
34522
|
+
});
|
|
34523
|
+
renderStandaloneSource({ path, ref });
|
|
34524
|
+
}
|
|
34525
|
+
}).then((next) => {
|
|
34526
|
+
if (signal?.aborted || !preview.isConnected || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
34527
|
+
return;
|
|
34528
|
+
next.dataset.sourcePane = "preview";
|
|
34529
|
+
next.hidden = preview.hidden;
|
|
34530
|
+
preview.replaceWith(next);
|
|
34531
|
+
onReplace(next);
|
|
34532
|
+
}).catch((err) => {
|
|
34533
|
+
console.error("Failed to apply preview syntax highlighting", err);
|
|
34534
|
+
});
|
|
34535
|
+
}, 0);
|
|
34536
|
+
}
|
|
34228
34537
|
function setPreferredSourceTab(tab) {
|
|
34229
34538
|
PREFERRED_SOURCE_TAB = tab;
|
|
34230
34539
|
}
|
|
@@ -34388,24 +34697,14 @@ code-viewer query agent-help`
|
|
|
34388
34697
|
card.appendChild(view);
|
|
34389
34698
|
setSourceCardState(card, "done");
|
|
34390
34699
|
}
|
|
34391
|
-
function renderSourceInternalPath(card, target
|
|
34700
|
+
function renderSourceInternalPath(card, target) {
|
|
34392
34701
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
34393
34702
|
const info = createSourceFileInfo(target, "internal metadata", {
|
|
34394
34703
|
loadMeta: false
|
|
34395
34704
|
});
|
|
34396
|
-
const extraChildren = [info];
|
|
34397
|
-
if (kind === "code-viewer") {
|
|
34398
|
-
const link2 = document.createElement("a");
|
|
34399
|
-
link2.className = "gdp-btn gdp-btn-sm gdp-source-download";
|
|
34400
|
-
link2.href = buildRawFileUrl(target);
|
|
34401
|
-
link2.textContent = "Download raw";
|
|
34402
|
-
link2.target = "_blank";
|
|
34403
|
-
link2.rel = "noreferrer";
|
|
34404
|
-
extraChildren.push(link2);
|
|
34405
|
-
}
|
|
34406
34705
|
const view = renderUnsupportedPreview({
|
|
34407
|
-
message:
|
|
34408
|
-
extraChildren
|
|
34706
|
+
message: "Git internal metadata is not previewed from the file viewer.",
|
|
34707
|
+
extraChildren: [info]
|
|
34409
34708
|
});
|
|
34410
34709
|
if (body)
|
|
34411
34710
|
body.replaceWith(view);
|
|
@@ -34462,7 +34761,7 @@ code-viewer query agent-help`
|
|
|
34462
34761
|
const tabs = document.createElement("div");
|
|
34463
34762
|
tabs.className = "gdp-source-tabs";
|
|
34464
34763
|
const { codeButton, previewButton } = appendFileViewTabs(tabs, { currentRange, setRoute, setPreferredSourceTab }, target, active, {
|
|
34465
|
-
includeFileTabs: STATE.route.screen === "file",
|
|
34764
|
+
includeFileTabs: STATE.route.screen === "file" && sourceInternalPathKind(target.path) !== "code-viewer",
|
|
34466
34765
|
previewable: !!options.previewable || active === "preview",
|
|
34467
34766
|
sourceTabClick: "manual",
|
|
34468
34767
|
...textValue != null ? { sourceCopyButton: createSourceCopyButton(textValue) } : {}
|
|
@@ -34486,9 +34785,9 @@ code-viewer query agent-help`
|
|
|
34486
34785
|
header.textContent = `${target.path} @ ${target.ref}`;
|
|
34487
34786
|
}
|
|
34488
34787
|
const lang = inferLang(target.path);
|
|
34788
|
+
const sourceShikiLang = normalizeSourceShikiLang(lang);
|
|
34489
34789
|
const usesVirtualSource = shouldVirtualizeSource(textValue, lines) && !isVirtualSourceDisabled();
|
|
34490
34790
|
const hljsRef = STATE.syntaxHighlight && usesVirtualSource ? await loadSyntaxHighlighter() : null;
|
|
34491
|
-
const sourceShikiRef = STATE.syntaxHighlight && !usesVirtualSource ? await loadSourceShikiHighlighter() : null;
|
|
34492
34791
|
if (signal?.aborted)
|
|
34493
34792
|
return false;
|
|
34494
34793
|
const previewable = isPreviewableSource(target.path);
|
|
@@ -34504,8 +34803,8 @@ code-viewer query agent-help`
|
|
|
34504
34803
|
tabsHost.hidden = false;
|
|
34505
34804
|
tabsHost.replaceChildren(tabs3);
|
|
34506
34805
|
}
|
|
34507
|
-
|
|
34508
|
-
syntaxHighlight:
|
|
34806
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34807
|
+
syntaxHighlight: false,
|
|
34509
34808
|
signal,
|
|
34510
34809
|
onNavigateMarkdown: (path, ref) => {
|
|
34511
34810
|
setRoute({
|
|
@@ -34521,9 +34820,19 @@ code-viewer query agent-help`
|
|
|
34521
34820
|
if (signal?.aborted)
|
|
34522
34821
|
return false;
|
|
34523
34822
|
preview.dataset.sourcePane = "preview";
|
|
34823
|
+
let previewHighlightScheduled = false;
|
|
34824
|
+
const ensurePreviewHighlight = () => {
|
|
34825
|
+
if (previewKind === "html" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
34826
|
+
return;
|
|
34827
|
+
previewHighlightScheduled = true;
|
|
34828
|
+
scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, (next) => {
|
|
34829
|
+
preview = next;
|
|
34830
|
+
});
|
|
34831
|
+
};
|
|
34524
34832
|
applyRenderedSourceTab(initialSourceTab, codeButton2, previewButton2, virtualCode, preview, false);
|
|
34525
34833
|
previewButton2?.addEventListener("click", () => {
|
|
34526
34834
|
applyRenderedSourceTab("preview", codeButton2, previewButton2, virtualCode, preview);
|
|
34835
|
+
ensurePreviewHighlight();
|
|
34527
34836
|
});
|
|
34528
34837
|
codeButton2?.addEventListener("click", () => {
|
|
34529
34838
|
applyRenderedSourceTab("code", codeButton2, previewButton2, virtualCode, preview);
|
|
@@ -34536,6 +34845,8 @@ code-viewer query agent-help`
|
|
|
34536
34845
|
body.replaceWith(view);
|
|
34537
34846
|
else
|
|
34538
34847
|
card.appendChild(view);
|
|
34848
|
+
if (initialSourceTab === "preview")
|
|
34849
|
+
ensurePreviewHighlight();
|
|
34539
34850
|
return true;
|
|
34540
34851
|
}
|
|
34541
34852
|
const { tabs: tabs2 } = createSourceTabs(target, "code", textValue, {
|
|
@@ -34561,8 +34872,6 @@ code-viewer query agent-help`
|
|
|
34561
34872
|
table2.className = "gdp-source-table";
|
|
34562
34873
|
table2.dataset.sourcePane = "code";
|
|
34563
34874
|
const tbody = document.createElement("tbody");
|
|
34564
|
-
const sourceShikiLang = normalizeSourceShikiLang(lang);
|
|
34565
|
-
const shikiLines = sourceShikiRef && sourceShikiLang ? sourceShikiLines(textValue, sourceShikiLang, sourceShikiRef) : null;
|
|
34566
34875
|
for (let index = 0;index < lines.length; index++) {
|
|
34567
34876
|
if (signal?.aborted)
|
|
34568
34877
|
return false;
|
|
@@ -34577,12 +34886,7 @@ code-viewer query agent-help`
|
|
|
34577
34886
|
bindSourceLineNumber(num, card, target, index + 1);
|
|
34578
34887
|
const code2 = document.createElement("td");
|
|
34579
34888
|
code2.className = "gdp-source-line-code";
|
|
34580
|
-
|
|
34581
|
-
code2.innerHTML = shikiLines[index] || " ";
|
|
34582
|
-
code2.classList.add("shiki");
|
|
34583
|
-
} else {
|
|
34584
|
-
code2.textContent = line || " ";
|
|
34585
|
-
}
|
|
34889
|
+
code2.textContent = line || " ";
|
|
34586
34890
|
tr.appendChild(num);
|
|
34587
34891
|
tr.appendChild(code2);
|
|
34588
34892
|
tbody.appendChild(tr);
|
|
@@ -34599,8 +34903,8 @@ code-viewer query agent-help`
|
|
|
34599
34903
|
tabsHost.replaceChildren(tabs);
|
|
34600
34904
|
}
|
|
34601
34905
|
if (previewable) {
|
|
34602
|
-
|
|
34603
|
-
syntaxHighlight:
|
|
34906
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(textValue, target, {
|
|
34907
|
+
syntaxHighlight: false,
|
|
34604
34908
|
signal,
|
|
34605
34909
|
onNavigateMarkdown: (path, ref) => {
|
|
34606
34910
|
setRoute({
|
|
@@ -34616,9 +34920,19 @@ code-viewer query agent-help`
|
|
|
34616
34920
|
if (signal?.aborted)
|
|
34617
34921
|
return false;
|
|
34618
34922
|
preview.dataset.sourcePane = "preview";
|
|
34923
|
+
let previewHighlightScheduled = false;
|
|
34924
|
+
const ensurePreviewHighlight = () => {
|
|
34925
|
+
if (previewKind === "html" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
34926
|
+
return;
|
|
34927
|
+
previewHighlightScheduled = true;
|
|
34928
|
+
scheduleMarkdownPreviewHighlight(preview, target, textValue, signal, (next) => {
|
|
34929
|
+
preview = next;
|
|
34930
|
+
});
|
|
34931
|
+
};
|
|
34619
34932
|
applyRenderedSourceTab(initialSourceTab, codeButton, previewButton, table2, preview, false);
|
|
34620
34933
|
previewButton?.addEventListener("click", () => {
|
|
34621
34934
|
applyRenderedSourceTab("preview", codeButton, previewButton, table2, preview);
|
|
34935
|
+
ensurePreviewHighlight();
|
|
34622
34936
|
});
|
|
34623
34937
|
codeButton?.addEventListener("click", () => {
|
|
34624
34938
|
applyRenderedSourceTab("code", codeButton, previewButton, table2, preview);
|
|
@@ -34633,6 +34947,10 @@ code-viewer query agent-help`
|
|
|
34633
34947
|
body.replaceWith(view);
|
|
34634
34948
|
else
|
|
34635
34949
|
card.appendChild(view);
|
|
34950
|
+
if (STATE.syntaxHighlight && sourceShikiLang)
|
|
34951
|
+
scheduleSourceHighlight(table2, target, textValue, sourceShikiLang, signal);
|
|
34952
|
+
if (initialSourceTab === "preview")
|
|
34953
|
+
ensurePreviewHighlight();
|
|
34636
34954
|
return true;
|
|
34637
34955
|
}
|
|
34638
34956
|
if (header)
|
|
@@ -34644,6 +34962,8 @@ code-viewer query agent-help`
|
|
|
34644
34962
|
body.replaceWith(view);
|
|
34645
34963
|
else
|
|
34646
34964
|
card.appendChild(view);
|
|
34965
|
+
if (STATE.syntaxHighlight && sourceShikiLang)
|
|
34966
|
+
scheduleSourceHighlight(table2, target, textValue, sourceShikiLang, signal);
|
|
34647
34967
|
return true;
|
|
34648
34968
|
}
|
|
34649
34969
|
function shouldVirtualizeSource(textValue, lines) {
|
|
@@ -34835,8 +35155,10 @@ code-viewer query agent-help`
|
|
|
34835
35155
|
matches = nextMatches;
|
|
34836
35156
|
active = matches.length ? Math.max(0, Math.min(active, matches.length - 1)) : -1;
|
|
34837
35157
|
count.textContent = matches.length ? `${active + 1} / ${matches.length}` : "0 / 0";
|
|
34838
|
-
if (active >= 0)
|
|
34839
|
-
|
|
35158
|
+
if (active >= 0) {
|
|
35159
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35160
|
+
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * rowHeight - rowHeight * 3);
|
|
35161
|
+
}
|
|
34840
35162
|
renderFn();
|
|
34841
35163
|
}).catch(() => {
|
|
34842
35164
|
if (version !== searchVersion)
|
|
@@ -34857,7 +35179,8 @@ code-viewer query agent-help`
|
|
|
34857
35179
|
return;
|
|
34858
35180
|
active = (active + direction + matches.length) % matches.length;
|
|
34859
35181
|
count.textContent = `${active + 1} / ${matches.length}`;
|
|
34860
|
-
|
|
35182
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35183
|
+
scroller.scrollTop = Math.max(0, (matches[active].line - 1) * rowHeight - rowHeight * 3);
|
|
34861
35184
|
renderFn();
|
|
34862
35185
|
};
|
|
34863
35186
|
input2.addEventListener("input", () => {
|
|
@@ -34951,7 +35274,7 @@ code-viewer query agent-help`
|
|
|
34951
35274
|
scroller.setAttribute("aria-label", `${target.path} source code`);
|
|
34952
35275
|
const spacer = document.createElement("div");
|
|
34953
35276
|
spacer.className = "gdp-source-virtual-spacer";
|
|
34954
|
-
spacer.style.height = `${Math.max(1, lines.length * VIRTUAL_SOURCE_ROW_HEIGHT)}px`;
|
|
35277
|
+
spacer.style.height = `${Math.max(1, lines.length * (sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT))}px`;
|
|
34955
35278
|
const windowEl = document.createElement("div");
|
|
34956
35279
|
windowEl.className = "gdp-source-virtual-window";
|
|
34957
35280
|
spacer.appendChild(windowEl);
|
|
@@ -34960,19 +35283,23 @@ code-viewer query agent-help`
|
|
|
34960
35283
|
let raf = 0;
|
|
34961
35284
|
let renderedStart = -1;
|
|
34962
35285
|
let renderedEnd = -1;
|
|
35286
|
+
let renderedRowHeight = -1;
|
|
34963
35287
|
let search = null;
|
|
34964
35288
|
const render = () => {
|
|
34965
35289
|
raf = 0;
|
|
35290
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35291
|
+
spacer.style.height = `${Math.max(1, lines.length * rowHeight)}px`;
|
|
34966
35292
|
const viewportHeight = scroller.clientHeight || window.innerHeight;
|
|
34967
35293
|
const overscan = 20;
|
|
34968
|
-
const start = Math.max(0, Math.floor(scroller.scrollTop /
|
|
34969
|
-
const end = Math.min(lines.length, Math.ceil((scroller.scrollTop + viewportHeight) /
|
|
34970
|
-
if (start === renderedStart && end === renderedEnd)
|
|
35294
|
+
const start = Math.max(0, Math.floor(scroller.scrollTop / rowHeight) - overscan);
|
|
35295
|
+
const end = Math.min(lines.length, Math.ceil((scroller.scrollTop + viewportHeight) / rowHeight) + overscan);
|
|
35296
|
+
if (start === renderedStart && end === renderedEnd && rowHeight === renderedRowHeight)
|
|
34971
35297
|
return;
|
|
34972
35298
|
renderedStart = start;
|
|
34973
35299
|
renderedEnd = end;
|
|
35300
|
+
renderedRowHeight = rowHeight;
|
|
34974
35301
|
windowEl.replaceChildren();
|
|
34975
|
-
windowEl.style.transform = `translateY(${start *
|
|
35302
|
+
windowEl.style.transform = `translateY(${start * rowHeight}px)`;
|
|
34976
35303
|
const fragment = document.createDocumentFragment();
|
|
34977
35304
|
for (let index = start;index < end; index++) {
|
|
34978
35305
|
const row = document.createElement("div");
|
|
@@ -35088,7 +35415,8 @@ code-viewer query agent-help`
|
|
|
35088
35415
|
const updateTotals = () => {
|
|
35089
35416
|
SOURCE_CURSOR_TOTALS.set(sourceCursorKey(target), totalRows);
|
|
35090
35417
|
summary.textContent = (complete ? totalRows.toLocaleString() : `${lines.size.toLocaleString()}+`) + " lines loaded from " + formatBytes(size) + ". More rows load as you scroll.";
|
|
35091
|
-
|
|
35418
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35419
|
+
spacer.style.height = `${Math.max(1, totalRows * rowHeight)}px`;
|
|
35092
35420
|
};
|
|
35093
35421
|
const loadPage = (line) => {
|
|
35094
35422
|
if (signal?.aborted || complete && line > totalRows)
|
|
@@ -35125,20 +35453,24 @@ code-viewer query agent-help`
|
|
|
35125
35453
|
let raf = 0;
|
|
35126
35454
|
let renderedStart = -1;
|
|
35127
35455
|
let renderedEnd = -1;
|
|
35456
|
+
let renderedRowHeight = -1;
|
|
35128
35457
|
let search = null;
|
|
35129
35458
|
let searchController = null;
|
|
35130
35459
|
const render = () => {
|
|
35131
35460
|
raf = 0;
|
|
35461
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35462
|
+
spacer.style.height = `${Math.max(1, totalRows * rowHeight)}px`;
|
|
35132
35463
|
const viewportHeight = scroller.clientHeight || window.innerHeight;
|
|
35133
35464
|
const overscan = 20;
|
|
35134
|
-
const start = Math.max(0, Math.floor(scroller.scrollTop /
|
|
35135
|
-
const end = Math.min(totalRows, Math.ceil((scroller.scrollTop + viewportHeight) /
|
|
35136
|
-
if (start === renderedStart && end === renderedEnd)
|
|
35465
|
+
const start = Math.max(0, Math.floor(scroller.scrollTop / rowHeight) - overscan);
|
|
35466
|
+
const end = Math.min(totalRows, Math.ceil((scroller.scrollTop + viewportHeight) / rowHeight) + overscan);
|
|
35467
|
+
if (start === renderedStart && end === renderedEnd && rowHeight === renderedRowHeight)
|
|
35137
35468
|
return;
|
|
35138
35469
|
renderedStart = start;
|
|
35139
35470
|
renderedEnd = end;
|
|
35471
|
+
renderedRowHeight = rowHeight;
|
|
35140
35472
|
windowEl.replaceChildren();
|
|
35141
|
-
windowEl.style.transform = `translateY(${start *
|
|
35473
|
+
windowEl.style.transform = `translateY(${start * rowHeight}px)`;
|
|
35142
35474
|
const fragment = document.createDocumentFragment();
|
|
35143
35475
|
for (let index = start;index < end; index++) {
|
|
35144
35476
|
const lineNumber = index + 1;
|
|
@@ -35367,8 +35699,8 @@ code-viewer query agent-help`
|
|
|
35367
35699
|
scrollStandaloneSourceLine(mounted, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35368
35700
|
return;
|
|
35369
35701
|
}
|
|
35370
|
-
if (mounted && state === "loading")
|
|
35371
|
-
return;
|
|
35702
|
+
if (mounted && state === "loading" && mounted._loadPromise)
|
|
35703
|
+
return mounted._loadPromise;
|
|
35372
35704
|
}
|
|
35373
35705
|
cancelActiveSourceLoad("navigation");
|
|
35374
35706
|
const req = ++SOURCE_REQ_SEQ;
|
|
@@ -35392,7 +35724,8 @@ code-viewer query agent-help`
|
|
|
35392
35724
|
currentRange,
|
|
35393
35725
|
setRoute,
|
|
35394
35726
|
setPreferredSourceTab,
|
|
35395
|
-
createFileBreadcrumb
|
|
35727
|
+
createFileBreadcrumb,
|
|
35728
|
+
createRepositoryWebLink: createRepositoryWebLink2
|
|
35396
35729
|
}, target, activeTab, internalKind ? { includeFileTabs: false, previewable: false } : {});
|
|
35397
35730
|
const pathActions = header.querySelector(".gdp-file-detail-path") || header;
|
|
35398
35731
|
pathActions.appendChild(createOpenPathButton(target.path, "file-parent", "open parent folder in OS"));
|
|
@@ -35403,7 +35736,7 @@ code-viewer query agent-help`
|
|
|
35403
35736
|
loadRepo();
|
|
35404
35737
|
}));
|
|
35405
35738
|
}
|
|
35406
|
-
if (
|
|
35739
|
+
if (internalKind !== "git") {
|
|
35407
35740
|
loadRawFileInfo(target).then((meta) => {
|
|
35408
35741
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35409
35742
|
return;
|
|
@@ -35428,94 +35761,103 @@ code-viewer query agent-help`
|
|
|
35428
35761
|
wrapper.appendChild(detailBody);
|
|
35429
35762
|
card.appendChild(wrapper);
|
|
35430
35763
|
mountFileShellCard({ $, repoFileTargetFromRoute, renderRepoBlobSidebar, placeSidebarToggle }, target, card, repoTarget);
|
|
35431
|
-
if (internalKind) {
|
|
35432
|
-
renderSourceInternalPath(card, target
|
|
35764
|
+
if (internalKind === "git") {
|
|
35765
|
+
renderSourceInternalPath(card, target);
|
|
35433
35766
|
return;
|
|
35434
35767
|
}
|
|
35435
35768
|
const controller = new AbortController;
|
|
35436
35769
|
ACTIVE_SOURCE_LOAD = { controller, req, target, card };
|
|
35437
35770
|
renderSourceLoading(card, target, () => cancelActiveSourceLoad("user"));
|
|
35438
|
-
|
|
35439
|
-
|
|
35440
|
-
|
|
35441
|
-
|
|
35442
|
-
|
|
35443
|
-
|
|
35444
|
-
|
|
35445
|
-
|
|
35446
|
-
|
|
35771
|
+
const sourceLoad = (async () => {
|
|
35772
|
+
try {
|
|
35773
|
+
let displayKind = sourceDisplayKind(target.path);
|
|
35774
|
+
let rawInfo = null;
|
|
35775
|
+
if (displayKind === "unsupported") {
|
|
35776
|
+
rawInfo = await loadRawFileInfo(target);
|
|
35777
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35778
|
+
return;
|
|
35779
|
+
if (await sourceLooksTextByContent(target, rawInfo, controller.signal)) {
|
|
35780
|
+
displayKind = "text";
|
|
35781
|
+
}
|
|
35447
35782
|
}
|
|
35448
|
-
|
|
35449
|
-
|
|
35450
|
-
|
|
35451
|
-
|
|
35452
|
-
|
|
35453
|
-
renderSourceUnsupported(card, target);
|
|
35454
|
-
return;
|
|
35455
|
-
}
|
|
35456
|
-
if (displayKind === "image" || displayKind === "video" || displayKind === "audio" || displayKind === "pdf") {
|
|
35457
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35783
|
+
if (displayKind === "unsupported") {
|
|
35784
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35785
|
+
return;
|
|
35786
|
+
finishSourceLoad(req);
|
|
35787
|
+
renderSourceUnsupported(card, target);
|
|
35458
35788
|
return;
|
|
35459
|
-
|
|
35460
|
-
|
|
35461
|
-
|
|
35462
|
-
|
|
35463
|
-
|
|
35464
|
-
|
|
35465
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35789
|
+
}
|
|
35790
|
+
if (displayKind === "image" || displayKind === "video" || displayKind === "audio" || displayKind === "pdf") {
|
|
35791
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35792
|
+
return;
|
|
35793
|
+
finishSourceLoad(req);
|
|
35794
|
+
renderSourceMedia(card, target, displayKind);
|
|
35466
35795
|
return;
|
|
35467
|
-
|
|
35468
|
-
|
|
35796
|
+
}
|
|
35797
|
+
if (displayKind === "text") {
|
|
35798
|
+
const meta = rawInfo ?? await loadRawFileInfo(target);
|
|
35799
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35800
|
+
return;
|
|
35801
|
+
if (!isVirtualSourceDisabled() && meta.size != null && meta.size >= VIRTUAL_SOURCE_SIZE_THRESHOLD) {
|
|
35802
|
+
const rendered2 = await renderPagedSourceText(card, target, meta.size, controller.signal);
|
|
35803
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35804
|
+
return;
|
|
35805
|
+
if (!rendered2) {
|
|
35806
|
+
finishSourceLoad(req);
|
|
35807
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35808
|
+
return;
|
|
35809
|
+
}
|
|
35810
|
+
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35811
|
+
setSourceCardState(card, "done");
|
|
35812
|
+
finishSourceLoad(req);
|
|
35813
|
+
return;
|
|
35814
|
+
}
|
|
35815
|
+
const response = await trackLoad(fetch(buildRawFileUrl(target), { signal: controller.signal }));
|
|
35469
35816
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35470
35817
|
return;
|
|
35471
|
-
if (!
|
|
35818
|
+
if (!response.ok) {
|
|
35472
35819
|
finishSourceLoad(req);
|
|
35473
35820
|
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35474
35821
|
return;
|
|
35475
35822
|
}
|
|
35823
|
+
const textValue = await response.text();
|
|
35824
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35825
|
+
return;
|
|
35826
|
+
const rendered = await renderSourceText(card, target, textValue, controller.signal);
|
|
35827
|
+
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35828
|
+
return;
|
|
35829
|
+
if (!rendered)
|
|
35830
|
+
return;
|
|
35476
35831
|
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35477
35832
|
setSourceCardState(card, "done");
|
|
35478
35833
|
finishSourceLoad(req);
|
|
35479
|
-
return;
|
|
35480
35834
|
}
|
|
35481
|
-
|
|
35835
|
+
} catch (err) {
|
|
35482
35836
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35483
35837
|
return;
|
|
35484
|
-
|
|
35485
|
-
|
|
35486
|
-
|
|
35838
|
+
finishSourceLoad(req);
|
|
35839
|
+
if (isAbortError3(err)) {
|
|
35840
|
+
renderSourceCancelled(card, target);
|
|
35487
35841
|
return;
|
|
35488
35842
|
}
|
|
35489
|
-
|
|
35490
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35491
|
-
return;
|
|
35492
|
-
const rendered = await renderSourceText(card, target, textValue, controller.signal);
|
|
35493
|
-
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35494
|
-
return;
|
|
35495
|
-
if (!rendered)
|
|
35496
|
-
return;
|
|
35497
|
-
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35498
|
-
setSourceCardState(card, "done");
|
|
35499
|
-
finishSourceLoad(req);
|
|
35843
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35500
35844
|
}
|
|
35501
|
-
}
|
|
35502
|
-
|
|
35503
|
-
|
|
35504
|
-
|
|
35505
|
-
|
|
35506
|
-
|
|
35507
|
-
|
|
35508
|
-
}
|
|
35509
|
-
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35510
|
-
}
|
|
35845
|
+
})();
|
|
35846
|
+
const completed = sourceLoad.finally(() => {
|
|
35847
|
+
if (card._loadPromise === completed)
|
|
35848
|
+
delete card._loadPromise;
|
|
35849
|
+
});
|
|
35850
|
+
card._loadPromise = completed;
|
|
35851
|
+
return completed;
|
|
35511
35852
|
}
|
|
35512
35853
|
function scrollStandaloneSourceLine(card, line) {
|
|
35513
35854
|
if (!line || line < 1)
|
|
35514
35855
|
return;
|
|
35515
35856
|
const virtualScroller = card.querySelector(".gdp-source-virtual-scroller");
|
|
35516
35857
|
if (virtualScroller) {
|
|
35517
|
-
const
|
|
35518
|
-
|
|
35858
|
+
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
35859
|
+
const centeredOffset = virtualScroller.clientHeight / 2 - rowHeight / 2;
|
|
35860
|
+
virtualScroller.scrollTop = Math.max(0, (line - 1) * rowHeight - Math.max(0, centeredOffset));
|
|
35519
35861
|
virtualScroller.__gdpRenderVirtualSource?.();
|
|
35520
35862
|
return;
|
|
35521
35863
|
}
|
|
@@ -35639,6 +35981,8 @@ code-viewer query agent-help`
|
|
|
35639
35981
|
let PENDING_G_SCOPE = null;
|
|
35640
35982
|
let PENDING_G_UNTIL = 0;
|
|
35641
35983
|
let PROJECT_NAME = "";
|
|
35984
|
+
let PROJECT_BRANCH = "";
|
|
35985
|
+
let REPO_WEB_URL = null;
|
|
35642
35986
|
let APP_SETTINGS = { version: 1 };
|
|
35643
35987
|
let VIEW_STATE = {
|
|
35644
35988
|
version: 1,
|
|
@@ -35783,11 +36127,14 @@ code-viewer query agent-help`
|
|
|
35783
36127
|
}
|
|
35784
36128
|
}
|
|
35785
36129
|
function setProjectBranch(branch) {
|
|
36130
|
+
PROJECT_BRANCH = branch;
|
|
35786
36131
|
const el = document.querySelector("#project-branch");
|
|
35787
36132
|
if (!el)
|
|
35788
36133
|
return;
|
|
35789
36134
|
el.hidden = !branch;
|
|
35790
|
-
|
|
36135
|
+
const name = el.querySelector(".project-branch-name");
|
|
36136
|
+
if (name)
|
|
36137
|
+
name.textContent = branch;
|
|
35791
36138
|
el.title = branch ? `Current branch: ${branch}` : "";
|
|
35792
36139
|
}
|
|
35793
36140
|
function mergeLocalSettings(patch) {
|
|
@@ -35974,7 +36321,14 @@ code-viewer query agent-help`
|
|
|
35974
36321
|
return normalizeViewerFontSize(APP_SETTINGS.codeFontSize);
|
|
35975
36322
|
}
|
|
35976
36323
|
function applyCodeFontSize(size = savedCodeFontSize()) {
|
|
36324
|
+
const previousLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
35977
36325
|
document.body.dataset.codeFontSize = size;
|
|
36326
|
+
const nextLineHeight = Number.parseFloat(getComputedStyle(document.body).getPropertyValue("--code-line-height"));
|
|
36327
|
+
document.querySelectorAll(".gdp-source-virtual-scroller").forEach((scroller) => {
|
|
36328
|
+
if (Number.isFinite(previousLineHeight) && previousLineHeight > 0 && Number.isFinite(nextLineHeight) && nextLineHeight > 0)
|
|
36329
|
+
scroller.scrollTop *= nextLineHeight / previousLineHeight;
|
|
36330
|
+
scroller.__gdpRenderVirtualSource?.();
|
|
36331
|
+
});
|
|
35978
36332
|
}
|
|
35979
36333
|
function savedSidebarFontSizeSetting() {
|
|
35980
36334
|
return normalizeViewerFontSize(APP_SETTINGS.sidebarFontSize);
|
|
@@ -36007,10 +36361,11 @@ code-viewer query agent-help`
|
|
|
36007
36361
|
const settings = await res.json();
|
|
36008
36362
|
setProjectName(settings.project || "");
|
|
36009
36363
|
setProjectBranch(settings.branch || "");
|
|
36364
|
+
REPO_WEB_URL = settings.repo_web_url;
|
|
36010
36365
|
const repoLink = document.querySelector("#repo-web-link");
|
|
36011
|
-
if (repoLink
|
|
36012
|
-
repoLink.href = settings.repo_web_url;
|
|
36013
|
-
repoLink.hidden =
|
|
36366
|
+
if (repoLink) {
|
|
36367
|
+
repoLink.href = settings.repo_web_url || "#";
|
|
36368
|
+
repoLink.hidden = !settings.repo_web_url;
|
|
36014
36369
|
}
|
|
36015
36370
|
SERVER_SCOPE_OMIT_DIRS_DEFAULT = normalizeScopeOmitDirs(settings.scope.omit_dirs_effective);
|
|
36016
36371
|
SERVER_SCOPE_EXCLUDE_NAMES_DEFAULT = normalizeScopeExcludeNames(settings.scope.exclude_names_effective);
|
|
@@ -36107,7 +36462,24 @@ code-viewer query agent-help`
|
|
|
36107
36462
|
const LINE_REF_PILL = createLineRefPill({
|
|
36108
36463
|
onClose: () => {
|
|
36109
36464
|
clearLineSelection();
|
|
36110
|
-
}
|
|
36465
|
+
},
|
|
36466
|
+
githubUrlForSelection: (path, start, end) => {
|
|
36467
|
+
const route = STATE.route;
|
|
36468
|
+
const ref = route.screen === "file" ? route.commit || route.ref : route.screen === "diff" ? route.range.to : "worktree";
|
|
36469
|
+
const target = buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
36470
|
+
ref,
|
|
36471
|
+
fallbackRef: PROJECT_BRANCH,
|
|
36472
|
+
path,
|
|
36473
|
+
kind: "blob",
|
|
36474
|
+
start,
|
|
36475
|
+
end
|
|
36476
|
+
});
|
|
36477
|
+
return target?.provider === "github" ? target.url : null;
|
|
36478
|
+
},
|
|
36479
|
+
copyReferenceLabel: () => uiText().global.copyLineReference,
|
|
36480
|
+
lineCountLabel: (count) => uiText().global.selectedLineCount(count),
|
|
36481
|
+
githubOpenTitle: () => uiText().global.githubSelectionOpen,
|
|
36482
|
+
githubCopyTitle: () => uiText().global.githubSelectionCopy
|
|
36111
36483
|
});
|
|
36112
36484
|
const DIFF_LINE_SELECT = createDiffLineSelect({ pill: LINE_REF_PILL });
|
|
36113
36485
|
function clearRenderedSourceLineTargets() {
|
|
@@ -36258,6 +36630,7 @@ code-viewer query agent-help`
|
|
|
36258
36630
|
renderRepoBlobSidebar: (path, ref) => REPO_VIEW.renderRepoBlobSidebar(path, ref),
|
|
36259
36631
|
placeSidebarToggle,
|
|
36260
36632
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
36633
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
36261
36634
|
createFileDetailMeta: (target, meta) => REPO_VIEW.createFileDetailMeta(target, meta),
|
|
36262
36635
|
createOpenPathButton,
|
|
36263
36636
|
createMoveToTrashButton: (path, onDeleted) => REPO_VIEW.createMoveToTrashButton(path, onDeleted),
|
|
@@ -36291,7 +36664,7 @@ code-viewer query agent-help`
|
|
|
36291
36664
|
currentRange,
|
|
36292
36665
|
trackLoad,
|
|
36293
36666
|
getSyntaxHighlight: () => STATE.syntaxHighlight,
|
|
36294
|
-
loadSourceShikiHighlighter: () => SOURCE_VIEW.loadSourceShikiHighlighter(),
|
|
36667
|
+
loadSourceShikiHighlighter: (lang) => SOURCE_VIEW.loadSourceShikiHighlighter(lang),
|
|
36295
36668
|
sourceShikiLines: (textValue, lang, highlighter) => SOURCE_VIEW.sourceShikiLines(textValue, lang, highlighter),
|
|
36296
36669
|
inferLang: (path) => SOURCE_VIEW.inferLang(path),
|
|
36297
36670
|
currentSourceLineTarget: (target) => SOURCE_VIEW.currentSourceLineTarget(target),
|
|
@@ -36299,6 +36672,7 @@ code-viewer query agent-help`
|
|
|
36299
36672
|
bindSourceLineNumber: (num, card, target, line) => SOURCE_VIEW.bindSourceLineNumber(num, card, target, line),
|
|
36300
36673
|
setPreferredSourceTab: (tab) => SOURCE_VIEW.setPreferredSourceTab(tab),
|
|
36301
36674
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
36675
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
36302
36676
|
removeStandaloneSource,
|
|
36303
36677
|
placeSidebarToggle,
|
|
36304
36678
|
escapeHtml: escapeHtml3,
|
|
@@ -36373,6 +36747,14 @@ code-viewer query agent-help`
|
|
|
36373
36747
|
const text3 = uiText().repo;
|
|
36374
36748
|
return submodule ? { label: text3.submoduleLabel, title: text3.submoduleTitle } : { label: text3.gitlinkLabel, title: text3.gitlinkTitle };
|
|
36375
36749
|
},
|
|
36750
|
+
repositoryWebTarget: (path, ref) => buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
36751
|
+
ref,
|
|
36752
|
+
fallbackRef: PROJECT_BRANCH,
|
|
36753
|
+
path,
|
|
36754
|
+
kind: "tree"
|
|
36755
|
+
}),
|
|
36756
|
+
openGithubLabel: () => uiText().repo.openGithub,
|
|
36757
|
+
openRepositoryWebLabel: () => uiText().repo.openRepositoryWeb,
|
|
36376
36758
|
fileBadge: (status) => DIFF_VIEW.fileBadge(status)
|
|
36377
36759
|
});
|
|
36378
36760
|
const {
|
|
@@ -36415,9 +36797,7 @@ code-viewer query agent-help`
|
|
|
36415
36797
|
queryHistory: "query history",
|
|
36416
36798
|
settings: "viewer settings",
|
|
36417
36799
|
theme: "toggle theme",
|
|
36418
|
-
product: "code viewer",
|
|
36419
36800
|
copyAiContext: "Copy AI context (Shift+Click to include code)",
|
|
36420
|
-
copyAiContextLabel: "AI context",
|
|
36421
36801
|
copyAiContextCopied: "Copied AI context",
|
|
36422
36802
|
copyAiContextCopiedWithCode: (lines) => `Copied AI context + code (${lines} line${lines === 1 ? "" : "s"})`,
|
|
36423
36803
|
copyAiContextFailed: "Copy failed",
|
|
@@ -36430,7 +36810,12 @@ code-viewer query agent-help`
|
|
|
36430
36810
|
cancelRequestsActiveTitle: (count) => `cancel ${count} in-flight request${count === 1 ? "" : "s"}`,
|
|
36431
36811
|
cancelRequestsInactiveTitle: "no in-flight requests",
|
|
36432
36812
|
brandHome: "Repository home",
|
|
36433
|
-
menuViews: "Views"
|
|
36813
|
+
menuViews: "Views",
|
|
36814
|
+
repoWebLink: "open repository web page",
|
|
36815
|
+
copyLineReference: "Copy AI reference",
|
|
36816
|
+
selectedLineCount: (count) => `${count} line${count === 1 ? "" : "s"}`,
|
|
36817
|
+
githubSelectionOpen: "Open selected lines on GitHub",
|
|
36818
|
+
githubSelectionCopy: "Copy GitHub link"
|
|
36434
36819
|
},
|
|
36435
36820
|
topbar: {
|
|
36436
36821
|
resetRange: "reset to HEAD .. worktree",
|
|
@@ -36441,15 +36826,13 @@ code-viewer query agent-help`
|
|
|
36441
36826
|
ignoreWs: "ignore whitespace changes (-w)",
|
|
36442
36827
|
ignoreWsLabel: "ws",
|
|
36443
36828
|
syntaxLoading: "loading...",
|
|
36444
|
-
|
|
36445
|
-
syntaxOff: "syntax off",
|
|
36829
|
+
syntax: "syntax",
|
|
36446
36830
|
syntaxOnTitle: "syntax highlighting on",
|
|
36447
36831
|
syntaxLoadingTitle: "loading syntax highlighter",
|
|
36448
36832
|
syntaxErrorTitle: "failed to load syntax highlighter",
|
|
36449
36833
|
syntaxOffTitle: "syntax highlighting off",
|
|
36450
36834
|
hideTests: "hide test files (test|spec)",
|
|
36451
36835
|
hideTestsLabel: "no test",
|
|
36452
|
-
autoUpdate: "auto",
|
|
36453
36836
|
autoUpdateOnTitle: "auto update on file change",
|
|
36454
36837
|
autoUpdateOffTitle: "auto update off — manual reload"
|
|
36455
36838
|
},
|
|
@@ -36536,7 +36919,9 @@ code-viewer query agent-help`
|
|
|
36536
36919
|
gitlinkLabel: "gitlink",
|
|
36537
36920
|
gitlinkTitle: "Git commit entry is not directly browsable at this ref",
|
|
36538
36921
|
submoduleLabel: "submodule",
|
|
36539
|
-
submoduleTitle: "Git submodule pinned to a commit"
|
|
36922
|
+
submoduleTitle: "Git submodule pinned to a commit",
|
|
36923
|
+
openGithub: "Open on GitHub",
|
|
36924
|
+
openRepositoryWeb: "Open repository web page"
|
|
36540
36925
|
},
|
|
36541
36926
|
history: {
|
|
36542
36927
|
title: "Commits",
|
|
@@ -36653,7 +37038,7 @@ code-viewer query agent-help`
|
|
|
36653
37038
|
display: "Display",
|
|
36654
37039
|
language: "Language",
|
|
36655
37040
|
fileListFontSize: "UI font size",
|
|
36656
|
-
fileListFontSizeHelp: "Applies to
|
|
37041
|
+
fileListFontSizeHelp: "Applies to all UI except code content.",
|
|
36657
37042
|
codeFontSize: "Code font size",
|
|
36658
37043
|
sizeSmall: "Small",
|
|
36659
37044
|
sizeRegular: "Regular",
|
|
@@ -36705,9 +37090,7 @@ code-viewer query agent-help`
|
|
|
36705
37090
|
queryHistory: "クエリ履歴",
|
|
36706
37091
|
settings: "ビューア設定",
|
|
36707
37092
|
theme: "テーマ切り替え",
|
|
36708
|
-
product: "code viewer",
|
|
36709
37093
|
copyAiContext: "AI 用コンテキストをコピー(Shift+Click でコードも添付)",
|
|
36710
|
-
copyAiContextLabel: "AI文脈",
|
|
36711
37094
|
copyAiContextCopied: "コピーしました",
|
|
36712
37095
|
copyAiContextCopiedWithCode: (lines) => `コピーしました(コード付き・${lines}行)`,
|
|
36713
37096
|
copyAiContextFailed: "コピーに失敗しました",
|
|
@@ -36720,7 +37103,12 @@ code-viewer query agent-help`
|
|
|
36720
37103
|
cancelRequestsActiveTitle: (count) => `実行中のリクエストを${count}件キャンセル`,
|
|
36721
37104
|
cancelRequestsInactiveTitle: "実行中のリクエストはありません",
|
|
36722
37105
|
brandHome: "リポジトリホーム",
|
|
36723
|
-
menuViews: "ビュー切り替え"
|
|
37106
|
+
menuViews: "ビュー切り替え",
|
|
37107
|
+
repoWebLink: "リポジトリのウェブページを開く",
|
|
37108
|
+
copyLineReference: "AI参照をコピー",
|
|
37109
|
+
selectedLineCount: (count) => `${count}行`,
|
|
37110
|
+
githubSelectionOpen: "選択行をGitHubで開く",
|
|
37111
|
+
githubSelectionCopy: "GitHubリンクをコピー"
|
|
36724
37112
|
},
|
|
36725
37113
|
topbar: {
|
|
36726
37114
|
resetRange: "HEAD .. worktree に戻す",
|
|
@@ -36731,15 +37119,13 @@ code-viewer query agent-help`
|
|
|
36731
37119
|
ignoreWs: "空白差分を無視 (-w)",
|
|
36732
37120
|
ignoreWsLabel: "空白",
|
|
36733
37121
|
syntaxLoading: "読み込み中...",
|
|
36734
|
-
|
|
36735
|
-
syntaxOff: "構文なし",
|
|
37122
|
+
syntax: "構文",
|
|
36736
37123
|
syntaxOnTitle: "シンタックスハイライト有効",
|
|
36737
37124
|
syntaxLoadingTitle: "シンタックスハイライトを読み込み中",
|
|
36738
37125
|
syntaxErrorTitle: "シンタックスハイライトの読み込みに失敗",
|
|
36739
37126
|
syntaxOffTitle: "シンタックスハイライト無効",
|
|
36740
37127
|
hideTests: "test/spec ファイルを隠す",
|
|
36741
37128
|
hideTestsLabel: "テスト非表示",
|
|
36742
|
-
autoUpdate: "自動",
|
|
36743
37129
|
autoUpdateOnTitle: "ファイル変更時に自動更新",
|
|
36744
37130
|
autoUpdateOffTitle: "自動更新オフ — 手動で再読み込み"
|
|
36745
37131
|
},
|
|
@@ -36826,7 +37212,9 @@ code-viewer query agent-help`
|
|
|
36826
37212
|
gitlinkLabel: "固定コミット",
|
|
36827
37213
|
gitlinkTitle: "特定のコミットに固定された参照です。この ref では直接開けません。",
|
|
36828
37214
|
submoduleLabel: "サブモジュール",
|
|
36829
|
-
submoduleTitle: "Git サブモジュール: 特定のコミットに固定されています。直接は開けません。"
|
|
37215
|
+
submoduleTitle: "Git サブモジュール: 特定のコミットに固定されています。直接は開けません。",
|
|
37216
|
+
openGithub: "GitHubで開く",
|
|
37217
|
+
openRepositoryWeb: "リポジトリのウェブページを開く"
|
|
36830
37218
|
},
|
|
36831
37219
|
history: {
|
|
36832
37220
|
title: "コミット",
|
|
@@ -36943,7 +37331,7 @@ code-viewer query agent-help`
|
|
|
36943
37331
|
display: "表示",
|
|
36944
37332
|
language: "言語",
|
|
36945
37333
|
fileListFontSize: "UIの文字サイズ",
|
|
36946
|
-
fileListFontSizeHelp: "
|
|
37334
|
+
fileListFontSizeHelp: "コード本文を除くUI全体に適用されます。",
|
|
36947
37335
|
codeFontSize: "コード表示の文字サイズ",
|
|
36948
37336
|
sizeSmall: "小",
|
|
36949
37337
|
sizeRegular: "標準",
|
|
@@ -37009,8 +37397,16 @@ code-viewer query agent-help`
|
|
|
37009
37397
|
if (route && text3.nav[route])
|
|
37010
37398
|
link2.textContent = text3.nav[route];
|
|
37011
37399
|
});
|
|
37012
|
-
|
|
37013
|
-
|
|
37400
|
+
const helpLink = document.querySelector(".global-icon-link[data-route='help']");
|
|
37401
|
+
if (helpLink) {
|
|
37402
|
+
helpLink.title = text3.nav.help;
|
|
37403
|
+
helpLink.setAttribute("aria-label", text3.nav.help);
|
|
37404
|
+
}
|
|
37405
|
+
const repoWebLink = document.querySelector("#repo-web-link");
|
|
37406
|
+
if (repoWebLink) {
|
|
37407
|
+
repoWebLink.title = text3.global.repoWebLink;
|
|
37408
|
+
repoWebLink.setAttribute("aria-label", text3.global.repoWebLink);
|
|
37409
|
+
}
|
|
37014
37410
|
document.querySelector(".brand")?.setAttribute("aria-label", text3.global.brandHome);
|
|
37015
37411
|
document.querySelector(".app-menu")?.setAttribute("aria-label", text3.global.menuViews);
|
|
37016
37412
|
const annotationsToggle = document.querySelector("#annotations-toggle");
|
|
@@ -37045,9 +37441,6 @@ code-viewer query agent-help`
|
|
|
37045
37441
|
if (copyAiContext) {
|
|
37046
37442
|
copyAiContext.title = text3.global.copyAiContext;
|
|
37047
37443
|
copyAiContext.setAttribute("aria-label", text3.global.copyAiContext);
|
|
37048
|
-
const copyAiContextLabel = copyAiContext.querySelector(".ai-context-label");
|
|
37049
|
-
if (copyAiContextLabel)
|
|
37050
|
-
copyAiContextLabel.textContent = text3.global.copyAiContextLabel;
|
|
37051
37444
|
}
|
|
37052
37445
|
const refReset = document.querySelector("#ref-reset");
|
|
37053
37446
|
if (refReset) {
|
|
@@ -37264,7 +37657,7 @@ code-viewer query agent-help`
|
|
|
37264
37657
|
const text3 = uiText();
|
|
37265
37658
|
btn.classList.toggle("active", STATE.syntaxHighlight);
|
|
37266
37659
|
btn.classList.toggle("loading", state === "loading");
|
|
37267
|
-
btn.textContent = state === "loading" ? text3.topbar.syntaxLoading :
|
|
37660
|
+
btn.textContent = state === "loading" ? text3.topbar.syntaxLoading : text3.topbar.syntax;
|
|
37268
37661
|
btn.setAttribute("aria-pressed", STATE.syntaxHighlight ? "true" : "false");
|
|
37269
37662
|
btn.title = STATE.syntaxHighlight ? text3.topbar.syntaxOnTitle : state === "loading" ? text3.topbar.syntaxLoadingTitle : state === "error" ? text3.topbar.syntaxErrorTitle : text3.topbar.syntaxOffTitle;
|
|
37270
37663
|
}
|
|
@@ -37649,8 +38042,9 @@ code-viewer query agent-help`
|
|
|
37649
38042
|
setRoute,
|
|
37650
38043
|
setPreferredSourceTab: (tab) => SOURCE_VIEW.setPreferredSourceTab(tab),
|
|
37651
38044
|
createFileBreadcrumb: (path, ref) => DIFF_VIEW.createFileBreadcrumb(path, ref),
|
|
38045
|
+
createRepositoryWebLink: createFileRepositoryWebLink,
|
|
37652
38046
|
emptyText: () => uiText().diff
|
|
37653
|
-
}, historyRoute);
|
|
38047
|
+
}, historyRoute, { loadSidebar: false });
|
|
37654
38048
|
activeFileHistoryDiffHost = mount.diffHost;
|
|
37655
38049
|
activeFileHistoryEmptyHost = mount.emptyHost;
|
|
37656
38050
|
return mount;
|
|
@@ -37705,7 +38099,17 @@ code-viewer query agent-help`
|
|
|
37705
38099
|
parkRangeForHistory();
|
|
37706
38100
|
setPageMode();
|
|
37707
38101
|
const mount = renderFileHistoryShell2(route);
|
|
37708
|
-
HISTORY_VIEW.enterHistory({ mount })
|
|
38102
|
+
HISTORY_VIEW.enterHistory({ mount }).then(async () => {
|
|
38103
|
+
const currentRoute = STATE.route;
|
|
38104
|
+
if (currentRoute.screen !== "file" || currentRoute.view !== "history" || currentRoute.path !== route.path || currentRoute.ref !== route.ref)
|
|
38105
|
+
return;
|
|
38106
|
+
await loadDiffFile(route.path);
|
|
38107
|
+
const routeAfterDiff = STATE.route;
|
|
38108
|
+
if (routeAfterDiff.screen !== "file" || routeAfterDiff.view !== "history" || routeAfterDiff.path !== route.path || routeAfterDiff.ref !== route.ref)
|
|
38109
|
+
return;
|
|
38110
|
+
await REPO_VIEW.renderRepoBlobSidebar(route.path, route.ref);
|
|
38111
|
+
placeSidebarToggle();
|
|
38112
|
+
});
|
|
37709
38113
|
return true;
|
|
37710
38114
|
}
|
|
37711
38115
|
return false;
|
|
@@ -37814,7 +38218,7 @@ code-viewer query agent-help`
|
|
|
37814
38218
|
applyHideTests();
|
|
37815
38219
|
}
|
|
37816
38220
|
function syncHeaderMenu() {
|
|
37817
|
-
document.querySelectorAll(".app-menu-item, .global-
|
|
38221
|
+
document.querySelectorAll(".app-menu-item, .global-icon-link").forEach((link2) => {
|
|
37818
38222
|
const fileRouteOwner = STATE.route.screen === "file" && (STATE.route.view === "blob" || STATE.route.view === "blame" || STATE.route.view === "history") ? "repo" : "diff";
|
|
37819
38223
|
const active = link2.dataset.route === STATE.route.screen || STATE.route.screen === "file" && link2.dataset.route === fileRouteOwner;
|
|
37820
38224
|
link2.classList.toggle("active", active);
|
|
@@ -37939,6 +38343,18 @@ code-viewer query agent-help`
|
|
|
37939
38343
|
});
|
|
37940
38344
|
return button;
|
|
37941
38345
|
}
|
|
38346
|
+
function createFileRepositoryWebLink(target) {
|
|
38347
|
+
const webTarget = buildRepositoryWebTarget(REPO_WEB_URL, {
|
|
38348
|
+
ref: target.ref,
|
|
38349
|
+
fallbackRef: PROJECT_BRANCH,
|
|
38350
|
+
path: target.path,
|
|
38351
|
+
kind: "blob"
|
|
38352
|
+
});
|
|
38353
|
+
if (!webTarget)
|
|
38354
|
+
return null;
|
|
38355
|
+
const label = webTarget.provider === "github" ? uiText().repo.openGithub : uiText().repo.openRepositoryWeb;
|
|
38356
|
+
return createRepositoryWebLink(webTarget, label);
|
|
38357
|
+
}
|
|
37942
38358
|
window.addEventListener("scroll", () => enqueueInitialLoads(), {
|
|
37943
38359
|
passive: true
|
|
37944
38360
|
});
|
|
@@ -38048,14 +38464,34 @@ code-viewer query agent-help`
|
|
|
38048
38464
|
if (cancelRequestsIcon) {
|
|
38049
38465
|
cancelRequestsIcon.innerHTML = iconSvg("octicon-x", X_16_PATH);
|
|
38050
38466
|
}
|
|
38467
|
+
const repoWebLinkIcon = document.querySelector("#repo-web-link .goi-icon");
|
|
38468
|
+
if (repoWebLinkIcon) {
|
|
38469
|
+
repoWebLinkIcon.innerHTML = iconSvg("octicon-mark-github", MARK_GITHUB_16_PATH);
|
|
38470
|
+
}
|
|
38471
|
+
const quickHelpIcon = document.querySelector("#quick-help-btn .goi-icon");
|
|
38472
|
+
if (quickHelpIcon) {
|
|
38473
|
+
quickHelpIcon.innerHTML = iconSvg("octicon-question", QUESTION_16_PATH);
|
|
38474
|
+
}
|
|
38475
|
+
const helpLinkIcon = document.querySelector(".global-icon-link[data-route='help'] .goi-icon");
|
|
38476
|
+
if (helpLinkIcon) {
|
|
38477
|
+
helpLinkIcon.innerHTML = iconSvg("octicon-book", BOOK_16_PATH);
|
|
38478
|
+
}
|
|
38479
|
+
const branchIcon = document.querySelector("#project-branch .goi-icon");
|
|
38480
|
+
if (branchIcon) {
|
|
38481
|
+
branchIcon.innerHTML = iconSvg("octicon-git-branch", GIT_BRANCH_16_PATH);
|
|
38482
|
+
}
|
|
38051
38483
|
}
|
|
38052
38484
|
function setRefActionIcons() {
|
|
38053
38485
|
const refReset = document.querySelector("#ref-reset");
|
|
38054
38486
|
if (refReset)
|
|
38055
|
-
refReset.innerHTML = iconSvg("octicon-
|
|
38487
|
+
refReset.innerHTML = iconSvg("octicon-undo", UNDO_16_PATH);
|
|
38056
38488
|
const reload = document.querySelector("#reload-prom");
|
|
38057
38489
|
if (reload)
|
|
38058
38490
|
reload.innerHTML = iconSvg("octicon-sync", SYNC_16_PATH);
|
|
38491
|
+
const refDots = document.querySelector(".ref-dots .goi-icon");
|
|
38492
|
+
if (refDots) {
|
|
38493
|
+
refDots.innerHTML = iconSvg("octicon-arrow-right", ARROW_RIGHT_16_PATH);
|
|
38494
|
+
}
|
|
38059
38495
|
}
|
|
38060
38496
|
applySidebarFontSize();
|
|
38061
38497
|
applyCodeFontSize();
|
|
@@ -39076,7 +39512,7 @@ code-viewer query agent-help`
|
|
|
39076
39512
|
}
|
|
39077
39513
|
window.addEventListener("popstate", applyRouteFromLocation);
|
|
39078
39514
|
window.addEventListener("pagehide", () => flushViewStatePatch(true));
|
|
39079
|
-
document.querySelectorAll(".app-menu-item, .global-
|
|
39515
|
+
document.querySelectorAll(".app-menu-item, .global-icon-link").forEach((link2) => {
|
|
39080
39516
|
if (link2.target === "_blank")
|
|
39081
39517
|
return;
|
|
39082
39518
|
link2.addEventListener("click", (e2) => {
|
|
@@ -39311,9 +39747,6 @@ code-viewer query agent-help`
|
|
|
39311
39747
|
btn.title = autoUpdateTitle;
|
|
39312
39748
|
btn.setAttribute("aria-label", autoUpdateTitle);
|
|
39313
39749
|
btn.setAttribute("aria-pressed", STATE.autoUpdate ? "true" : "false");
|
|
39314
|
-
const label = btn.querySelector(".auto-update-label");
|
|
39315
|
-
if (label)
|
|
39316
|
-
label.textContent = text3.topbar.autoUpdate;
|
|
39317
39750
|
}
|
|
39318
39751
|
function setAutoUpdate(on) {
|
|
39319
39752
|
STATE.autoUpdate = on;
|