@youtyan/code-viewer 0.12.0 → 0.13.0
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 +14 -0
- package/dist/code-viewer.js +1515 -246
- package/package.json +1 -1
- package/web/app.js +2178 -328
- package/web/index.html +5 -0
- package/web/style.css +335 -39
package/web/app.js
CHANGED
|
@@ -1119,6 +1119,7 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
1119
1119
|
var PENCIL_16_PATH = "M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.609Zm.176 4.823L9.75 4.81l-6.286 6.287a.253.253 0 0 0-.064.108l-.558 1.953 1.953-.558a.253.253 0 0 0 .108-.064Zm1.238-3.763a.25.25 0 0 0-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 0 0 0-.354Z";
|
|
1120
1120
|
var COMMENT_DISCUSSION_16_PATH = "M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z";
|
|
1121
1121
|
var GRABBER_16_PATH = "M10 13h4v-2h-4v2Zm-8 0h4v-2H2v2Zm8-6h4V5h-4v2ZM2 7h4V5H2v2Zm8-6v2h4V1h-4ZM2 3h4V1H2v2Z";
|
|
1122
|
+
var KEBAB_16_PATH = "M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z";
|
|
1122
1123
|
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";
|
|
1123
1124
|
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";
|
|
1124
1125
|
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";
|
|
@@ -1795,6 +1796,19 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
1795
1796
|
lang: params.get("lang") || "en",
|
|
1796
1797
|
section: params.get("section") || "overview"
|
|
1797
1798
|
};
|
|
1799
|
+
case "/worktree": {
|
|
1800
|
+
const wt = params.get("wt") || "";
|
|
1801
|
+
const file = params.get("file") || "";
|
|
1802
|
+
const rawOrigin = params.get("origin");
|
|
1803
|
+
const origin = rawOrigin === "committed" || rawOrigin === "uncommitted" ? rawOrigin : void 0;
|
|
1804
|
+
return {
|
|
1805
|
+
screen: "worktree",
|
|
1806
|
+
...wt ? { wt } : {},
|
|
1807
|
+
...file ? { file } : {},
|
|
1808
|
+
...origin ? { origin } : {},
|
|
1809
|
+
range
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1798
1812
|
case "/doctor":
|
|
1799
1813
|
return {
|
|
1800
1814
|
screen: "repo",
|
|
@@ -1878,6 +1892,14 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
1878
1892
|
return "/file?path=" + encodeURIComponent(route.path) + "&ref=" + encodeURIComponent(route.ref || "worktree") + "&from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "") + (route.virtual === "off" ? "&virtual=off" : "");
|
|
1879
1893
|
case "diff":
|
|
1880
1894
|
return "/todif?from=" + encodeURIComponent(route.range.from || "") + "&to=" + encodeURIComponent(route.range.to || "worktree") + (route.path ? `&path=${encodeURIComponent(route.path)}` : "") + (route.line ? `&line=${encodeURIComponent(formatLineTarget(route.line))}` : "");
|
|
1895
|
+
case "worktree": {
|
|
1896
|
+
const params = new URLSearchParams();
|
|
1897
|
+
if (route.wt) params.set("wt", route.wt);
|
|
1898
|
+
if (route.file) params.set("file", route.file);
|
|
1899
|
+
if (route.file && route.origin) params.set("origin", route.origin);
|
|
1900
|
+
const qs = params.toString();
|
|
1901
|
+
return `/worktree${qs ? `?${qs}` : ""}`;
|
|
1902
|
+
}
|
|
1881
1903
|
case "help": {
|
|
1882
1904
|
const params = new URLSearchParams();
|
|
1883
1905
|
if (route.lang && route.lang !== "en") params.set("lang", route.lang);
|
|
@@ -1937,8 +1959,8 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
1937
1959
|
const qs = params.toString();
|
|
1938
1960
|
return qs ? `${base2}?${qs}` : base2;
|
|
1939
1961
|
}
|
|
1940
|
-
function withDoctorOverlay(url,
|
|
1941
|
-
return withQueryParam(url, "doctor",
|
|
1962
|
+
function withDoctorOverlay(url, open2) {
|
|
1963
|
+
return withQueryParam(url, "doctor", open2 ? "open" : null);
|
|
1942
1964
|
}
|
|
1943
1965
|
function parseToolsOverlay(search) {
|
|
1944
1966
|
const raw = new URLSearchParams(search).get("tools");
|
|
@@ -7924,8 +7946,8 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
7924
7946
|
compile(this);
|
|
7925
7947
|
return this;
|
|
7926
7948
|
}
|
|
7927
|
-
this.__tlds__ = this.__tlds__.concat(list2).sort().filter(function(
|
|
7928
|
-
return
|
|
7949
|
+
this.__tlds__ = this.__tlds__.concat(list2).sort().filter(function(el2, idx, arr) {
|
|
7950
|
+
return el2 !== arr[idx - 1];
|
|
7929
7951
|
}).reverse();
|
|
7930
7952
|
compile(this);
|
|
7931
7953
|
return this;
|
|
@@ -9165,8 +9187,8 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
9165
9187
|
const markerRe = new RegExp(`^\\[!(${ALERT_TYPES.join("|")})\\]\\s*`, "i");
|
|
9166
9188
|
let i2 = 0;
|
|
9167
9189
|
while (i2 < state.tokens.length) {
|
|
9168
|
-
const
|
|
9169
|
-
if (
|
|
9190
|
+
const open2 = state.tokens[i2];
|
|
9191
|
+
if (open2.type !== "blockquote_open") {
|
|
9170
9192
|
i2++;
|
|
9171
9193
|
continue;
|
|
9172
9194
|
}
|
|
@@ -9191,7 +9213,7 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
9191
9213
|
continue;
|
|
9192
9214
|
}
|
|
9193
9215
|
const type = match2[1].toLowerCase();
|
|
9194
|
-
|
|
9216
|
+
open2.attrSet("class", `markdown-alert markdown-alert-${type}`);
|
|
9195
9217
|
const rest = first.content.slice(match2[0].length);
|
|
9196
9218
|
if (rest) {
|
|
9197
9219
|
first.content = rest;
|
|
@@ -9729,8 +9751,8 @@ ${frontmatter.yaml}
|
|
|
9729
9751
|
|
|
9730
9752
|
// web-src/views/diff-line-select.ts
|
|
9731
9753
|
var SELECTED_CLASS = "gdp-diff-line-selected";
|
|
9732
|
-
function cardPath(
|
|
9733
|
-
return
|
|
9754
|
+
function cardPath(el2) {
|
|
9755
|
+
return el2.closest(".gdp-file-shell[data-path]")?.dataset.path || "";
|
|
9734
9756
|
}
|
|
9735
9757
|
function afterLineFromCell(cell) {
|
|
9736
9758
|
const sideCell = cell.closest("td.d2h-code-side-linenumber");
|
|
@@ -10076,6 +10098,7 @@ ${frontmatter.yaml}
|
|
|
10076
10098
|
const submit = document.createElement("button");
|
|
10077
10099
|
submit.type = "button";
|
|
10078
10100
|
submit.className = "gdp-btn gdp-btn-sm";
|
|
10101
|
+
if (opts.danger) submit.classList.add("gdp-dialog-danger");
|
|
10079
10102
|
submit.textContent = opts.submitLabel ?? "Save";
|
|
10080
10103
|
const error2 = document.createElement("div");
|
|
10081
10104
|
error2.className = "gdp-dialog-error";
|
|
@@ -10218,10 +10241,10 @@ ${frontmatter.yaml}
|
|
|
10218
10241
|
function updateDatabaseCaptureButton() {
|
|
10219
10242
|
annotationCaptureDb.hidden = deps.getRoute().screen !== "database";
|
|
10220
10243
|
}
|
|
10221
|
-
function setAnnotationPanelOpen(
|
|
10222
|
-
annotationPanel.hidden = !
|
|
10223
|
-
document.body.classList.toggle("annotation-panel-open",
|
|
10224
|
-
if (
|
|
10244
|
+
function setAnnotationPanelOpen(open2) {
|
|
10245
|
+
annotationPanel.hidden = !open2;
|
|
10246
|
+
document.body.classList.toggle("annotation-panel-open", open2);
|
|
10247
|
+
if (open2) {
|
|
10225
10248
|
annotationPanelDismissed = false;
|
|
10226
10249
|
const qhPanel = document.getElementById("query-history-panel");
|
|
10227
10250
|
if (qhPanel) qhPanel.hidden = true;
|
|
@@ -10232,7 +10255,7 @@ ${frontmatter.yaml}
|
|
|
10232
10255
|
updateActiveHighlights();
|
|
10233
10256
|
syncInlineAnnotationActive();
|
|
10234
10257
|
}
|
|
10235
|
-
deps.setAnnotationPanelOpenState(
|
|
10258
|
+
deps.setAnnotationPanelOpenState(open2);
|
|
10236
10259
|
syncSessionUrl();
|
|
10237
10260
|
applyInlineAnnotations();
|
|
10238
10261
|
}
|
|
@@ -10364,20 +10387,20 @@ ${frontmatter.yaml}
|
|
|
10364
10387
|
}
|
|
10365
10388
|
function applyDatabaseAnnotations(session) {
|
|
10366
10389
|
if (databaseAnnotationsMounted) {
|
|
10367
|
-
document.querySelectorAll(".gdp-db-annotation-strip").forEach((
|
|
10368
|
-
|
|
10390
|
+
document.querySelectorAll(".gdp-db-annotation-strip").forEach((el2) => {
|
|
10391
|
+
el2.remove();
|
|
10369
10392
|
});
|
|
10370
10393
|
databaseAnnotationsMounted = false;
|
|
10371
10394
|
}
|
|
10372
10395
|
if (!session || deps.getRoute().screen !== "database") return;
|
|
10373
|
-
const
|
|
10374
|
-
if (!
|
|
10396
|
+
const matches2 = session.entries.filter(databaseAnnotationMatchesRoute);
|
|
10397
|
+
if (!matches2.length) return;
|
|
10375
10398
|
const root = document.querySelector(".db-root");
|
|
10376
10399
|
if (!root) return;
|
|
10377
10400
|
const strip = document.createElement("section");
|
|
10378
10401
|
strip.className = "gdp-db-annotation-strip";
|
|
10379
10402
|
strip.setAttribute("aria-label", "Datastore annotations");
|
|
10380
|
-
for (const entry of
|
|
10403
|
+
for (const entry of matches2) {
|
|
10381
10404
|
strip.appendChild(
|
|
10382
10405
|
buildDatabaseAnnotationBlock(entry, {
|
|
10383
10406
|
index: session.entries.indexOf(entry),
|
|
@@ -10493,10 +10516,10 @@ ${frontmatter.yaml}
|
|
|
10493
10516
|
function syncInlineAnnotationWidths() {
|
|
10494
10517
|
document.querySelectorAll(".gdp-annotation-inline").forEach((box) => {
|
|
10495
10518
|
let scroller = null;
|
|
10496
|
-
for (let
|
|
10497
|
-
const overflowX = getComputedStyle(
|
|
10519
|
+
for (let el2 = box.parentElement; el2 && el2 !== document.body; el2 = el2.parentElement) {
|
|
10520
|
+
const overflowX = getComputedStyle(el2).overflowX;
|
|
10498
10521
|
if (overflowX === "auto" || overflowX === "scroll") {
|
|
10499
|
-
scroller =
|
|
10522
|
+
scroller = el2;
|
|
10500
10523
|
break;
|
|
10501
10524
|
}
|
|
10502
10525
|
}
|
|
@@ -10695,8 +10718,8 @@ ${frontmatter.yaml}
|
|
|
10695
10718
|
const head = annotationDetail.querySelector(
|
|
10696
10719
|
".annotation-detail-head"
|
|
10697
10720
|
);
|
|
10698
|
-
head?.querySelectorAll(".annotation-detail-head-action").forEach((
|
|
10699
|
-
|
|
10721
|
+
head?.querySelectorAll(".annotation-detail-head-action").forEach((el2) => {
|
|
10722
|
+
el2.remove();
|
|
10700
10723
|
});
|
|
10701
10724
|
const body = $("#annotation-detail-body");
|
|
10702
10725
|
body.replaceChildren();
|
|
@@ -10850,25 +10873,25 @@ ${frontmatter.yaml}
|
|
|
10850
10873
|
const item = document.createElement("li");
|
|
10851
10874
|
item.dataset.entryId = entry.id;
|
|
10852
10875
|
item.classList.toggle("active", entry.id === activeAnnotationId);
|
|
10853
|
-
const
|
|
10854
|
-
|
|
10855
|
-
|
|
10876
|
+
const open2 = document.createElement("button");
|
|
10877
|
+
open2.type = "button";
|
|
10878
|
+
open2.className = "annotation-entry-open";
|
|
10856
10879
|
const location2 = document.createElement("span");
|
|
10857
10880
|
location2.className = "annotation-entry-location";
|
|
10858
10881
|
location2.textContent = annotationLocationLabel(entry);
|
|
10859
10882
|
const summary = document.createElement("span");
|
|
10860
10883
|
summary.className = "annotation-entry-summary";
|
|
10861
10884
|
summary.textContent = annotationEntrySummary(entry);
|
|
10862
|
-
|
|
10885
|
+
open2.append(location2, summary);
|
|
10863
10886
|
const entryTimeLabel = annotationTimeLabel(entry.created_at);
|
|
10864
10887
|
if (entryTimeLabel) {
|
|
10865
10888
|
const time2 = document.createElement("span");
|
|
10866
10889
|
time2.className = "annotation-entry-time";
|
|
10867
10890
|
time2.textContent = entryTimeLabel;
|
|
10868
10891
|
time2.title = entry.created_at;
|
|
10869
|
-
|
|
10892
|
+
open2.appendChild(time2);
|
|
10870
10893
|
}
|
|
10871
|
-
|
|
10894
|
+
open2.addEventListener("click", () => {
|
|
10872
10895
|
void openAnnotationEntry(entry.id);
|
|
10873
10896
|
});
|
|
10874
10897
|
const remove = annotationIconButton(
|
|
@@ -10886,7 +10909,7 @@ ${frontmatter.yaml}
|
|
|
10886
10909
|
if (!ok) return;
|
|
10887
10910
|
void postAnnotationAction({ action: "delete", id: entry.id });
|
|
10888
10911
|
});
|
|
10889
|
-
item.append(
|
|
10912
|
+
item.append(open2, remove);
|
|
10890
10913
|
list2.appendChild(item);
|
|
10891
10914
|
});
|
|
10892
10915
|
sessionEl.appendChild(list2);
|
|
@@ -10894,13 +10917,13 @@ ${frontmatter.yaml}
|
|
|
10894
10917
|
}
|
|
10895
10918
|
}
|
|
10896
10919
|
function updateActiveHighlights() {
|
|
10897
|
-
annotationSessionsEl.querySelectorAll(".annotation-session").forEach((
|
|
10898
|
-
|
|
10920
|
+
annotationSessionsEl.querySelectorAll(".annotation-session").forEach((el2) => {
|
|
10921
|
+
el2.classList.toggle("active", el2.dataset.sessionId === activeSessionId);
|
|
10899
10922
|
});
|
|
10900
|
-
annotationSessionsEl.querySelectorAll(".annotation-entries li").forEach((
|
|
10901
|
-
|
|
10923
|
+
annotationSessionsEl.querySelectorAll(".annotation-entries li").forEach((el2) => {
|
|
10924
|
+
el2.classList.toggle(
|
|
10902
10925
|
"active",
|
|
10903
|
-
|
|
10926
|
+
el2.dataset.entryId === activeAnnotationId
|
|
10904
10927
|
);
|
|
10905
10928
|
});
|
|
10906
10929
|
}
|
|
@@ -10939,8 +10962,8 @@ ${frontmatter.yaml}
|
|
|
10939
10962
|
const head = annotationDetail.querySelector(
|
|
10940
10963
|
".annotation-detail-head"
|
|
10941
10964
|
);
|
|
10942
|
-
head?.querySelectorAll(".annotation-detail-head-action").forEach((
|
|
10943
|
-
|
|
10965
|
+
head?.querySelectorAll(".annotation-detail-head-action").forEach((el2) => {
|
|
10966
|
+
el2.remove();
|
|
10944
10967
|
});
|
|
10945
10968
|
const copyRef = createCopyRefButton(entry, "annotation-detail-head-action");
|
|
10946
10969
|
const edit = annotationIconButton(
|
|
@@ -11532,8 +11555,8 @@ ${frontmatter.yaml}
|
|
|
11532
11555
|
function createBlameView(deps) {
|
|
11533
11556
|
let activeGeneration = 0;
|
|
11534
11557
|
function cleanup() {
|
|
11535
|
-
document.querySelectorAll(".gdp-standalone-blame").forEach((
|
|
11536
|
-
|
|
11558
|
+
document.querySelectorAll(".gdp-standalone-blame").forEach((el2) => {
|
|
11559
|
+
el2.remove();
|
|
11537
11560
|
});
|
|
11538
11561
|
}
|
|
11539
11562
|
function colourBarFor(commit, bin, binCount) {
|
|
@@ -13102,16 +13125,16 @@ ${frontmatter.yaml}
|
|
|
13102
13125
|
}
|
|
13103
13126
|
|
|
13104
13127
|
// web-src/views/database/pane-status.ts
|
|
13105
|
-
function setPaneStatus(
|
|
13106
|
-
|
|
13128
|
+
function setPaneStatus(el2, message, options = {}) {
|
|
13129
|
+
el2.innerHTML = "";
|
|
13107
13130
|
options.afterClear?.();
|
|
13108
13131
|
const note = document.createElement("div");
|
|
13109
13132
|
note.className = options.error ? "db-pane-error" : "db-pane-note";
|
|
13110
13133
|
note.textContent = message;
|
|
13111
|
-
|
|
13134
|
+
el2.appendChild(note);
|
|
13112
13135
|
}
|
|
13113
|
-
function setPaneEmpty(
|
|
13114
|
-
|
|
13136
|
+
function setPaneEmpty(el2, message, options = {}) {
|
|
13137
|
+
el2.innerHTML = "";
|
|
13115
13138
|
const empty = document.createElement("div");
|
|
13116
13139
|
empty.className = "db-pane-empty";
|
|
13117
13140
|
const icon = document.createElement("div");
|
|
@@ -13127,7 +13150,7 @@ ${frontmatter.yaml}
|
|
|
13127
13150
|
hint.textContent = options.hint;
|
|
13128
13151
|
empty.appendChild(hint);
|
|
13129
13152
|
}
|
|
13130
|
-
|
|
13153
|
+
el2.appendChild(empty);
|
|
13131
13154
|
}
|
|
13132
13155
|
|
|
13133
13156
|
// web-src/views/database/dynamodb-explorer.ts
|
|
@@ -14821,9 +14844,9 @@ ${frontmatter.yaml}
|
|
|
14821
14844
|
}
|
|
14822
14845
|
function createErDiagram(deps = {}) {
|
|
14823
14846
|
const text3 = () => deps.getText?.() ?? dbText("en");
|
|
14824
|
-
const
|
|
14825
|
-
|
|
14826
|
-
|
|
14847
|
+
const el2 = document.createElement("div");
|
|
14848
|
+
el2.className = "db-er-diagram";
|
|
14849
|
+
el2.hidden = true;
|
|
14827
14850
|
const toolbar = document.createElement("div");
|
|
14828
14851
|
toolbar.className = "db-er-toolbar";
|
|
14829
14852
|
const zoomIn = document.createElement("button");
|
|
@@ -14853,7 +14876,7 @@ ${frontmatter.yaml}
|
|
|
14853
14876
|
});
|
|
14854
14877
|
const container = viewport.container;
|
|
14855
14878
|
const svgWrap = viewport.content;
|
|
14856
|
-
|
|
14879
|
+
el2.append(toolbar, container);
|
|
14857
14880
|
let lastMarkup = "";
|
|
14858
14881
|
zoomIn.addEventListener("click", () => viewport.zoomIn());
|
|
14859
14882
|
zoomOut.addEventListener("click", () => viewport.zoomOut());
|
|
@@ -14872,7 +14895,7 @@ ${frontmatter.yaml}
|
|
|
14872
14895
|
}
|
|
14873
14896
|
});
|
|
14874
14897
|
async function render(schema, columnsMap) {
|
|
14875
|
-
|
|
14898
|
+
el2.hidden = false;
|
|
14876
14899
|
svgWrap.innerHTML = "";
|
|
14877
14900
|
viewport.reset();
|
|
14878
14901
|
const tables = schema.tables.filter((t2) => t2.type === "table");
|
|
@@ -14898,7 +14921,7 @@ ${frontmatter.yaml}
|
|
|
14898
14921
|
}
|
|
14899
14922
|
}
|
|
14900
14923
|
function clear() {
|
|
14901
|
-
|
|
14924
|
+
el2.hidden = true;
|
|
14902
14925
|
svgWrap.innerHTML = "";
|
|
14903
14926
|
lastMarkup = "";
|
|
14904
14927
|
}
|
|
@@ -14914,14 +14937,14 @@ ${frontmatter.yaml}
|
|
|
14914
14937
|
copyBtn.title = t2.copyMermaidTitle;
|
|
14915
14938
|
if (copyBtn.textContent !== t2.copied) copyBtn.textContent = t2.copyMermaid;
|
|
14916
14939
|
}
|
|
14917
|
-
return { el, render, clear, dispose, localize };
|
|
14940
|
+
return { el: el2, render, clear, dispose, localize };
|
|
14918
14941
|
}
|
|
14919
14942
|
|
|
14920
14943
|
// web-src/views/database/global-search-view.ts
|
|
14921
14944
|
function createGlobalSearchView(deps) {
|
|
14922
14945
|
const text3 = () => deps.getText?.() ?? dbText("en");
|
|
14923
|
-
const
|
|
14924
|
-
|
|
14946
|
+
const el2 = document.createElement("div");
|
|
14947
|
+
el2.className = "db-global-search";
|
|
14925
14948
|
const header = document.createElement("div");
|
|
14926
14949
|
header.className = "db-global-search-header";
|
|
14927
14950
|
const input2 = document.createElement("input");
|
|
@@ -14951,7 +14974,7 @@ ${frontmatter.yaml}
|
|
|
14951
14974
|
progress.hidden = true;
|
|
14952
14975
|
const results = document.createElement("div");
|
|
14953
14976
|
results.className = "db-global-search-results";
|
|
14954
|
-
|
|
14977
|
+
el2.append(header, optionsRow, progress, results);
|
|
14955
14978
|
let currentJobId = null;
|
|
14956
14979
|
let pollTimer = null;
|
|
14957
14980
|
let disposed = false;
|
|
@@ -15147,7 +15170,7 @@ ${frontmatter.yaml}
|
|
|
15147
15170
|
cancelBtn.textContent = t2.cancelButton;
|
|
15148
15171
|
nonTextText.textContent = t2.includeNonText;
|
|
15149
15172
|
}
|
|
15150
|
-
return { el, setSearch, getSearch, dispose, localize };
|
|
15173
|
+
return { el: el2, setSearch, getSearch, dispose, localize };
|
|
15151
15174
|
}
|
|
15152
15175
|
|
|
15153
15176
|
// web-src/views/database/pref-toggle.ts
|
|
@@ -15196,8 +15219,8 @@ ${frontmatter.yaml}
|
|
|
15196
15219
|
var MAX_HISTORY = 50;
|
|
15197
15220
|
function createQueryEditor(callbacks) {
|
|
15198
15221
|
const text3 = () => callbacks.getText?.() ?? dbText("en");
|
|
15199
|
-
const
|
|
15200
|
-
|
|
15222
|
+
const el2 = document.createElement("div");
|
|
15223
|
+
el2.className = "db-query-editor";
|
|
15201
15224
|
const inputArea = document.createElement("div");
|
|
15202
15225
|
inputArea.className = "db-query-input";
|
|
15203
15226
|
const editorWrap = document.createElement("div");
|
|
@@ -15275,7 +15298,7 @@ ${frontmatter.yaml}
|
|
|
15275
15298
|
const resultArea = document.createElement("div");
|
|
15276
15299
|
resultArea.className = "db-query-result";
|
|
15277
15300
|
resultArea.hidden = true;
|
|
15278
|
-
|
|
15301
|
+
el2.append(inputArea, resultArea);
|
|
15279
15302
|
async function run() {
|
|
15280
15303
|
const sql = textarea.value.trim();
|
|
15281
15304
|
if (!sql) return;
|
|
@@ -15510,7 +15533,7 @@ ${frontmatter.yaml}
|
|
|
15510
15533
|
historyBtn.title = t2.localHistoryTitle;
|
|
15511
15534
|
}
|
|
15512
15535
|
return {
|
|
15513
|
-
el,
|
|
15536
|
+
el: el2,
|
|
15514
15537
|
focus,
|
|
15515
15538
|
setSql,
|
|
15516
15539
|
getSql,
|
|
@@ -15524,8 +15547,8 @@ ${frontmatter.yaml}
|
|
|
15524
15547
|
// web-src/views/database/query-history-view.ts
|
|
15525
15548
|
function createQueryHistoryView(callbacks) {
|
|
15526
15549
|
const text3 = () => callbacks.getText?.() ?? dbText("en");
|
|
15527
|
-
const
|
|
15528
|
-
|
|
15550
|
+
const el2 = document.createElement("div");
|
|
15551
|
+
el2.className = "db-query-history";
|
|
15529
15552
|
const toolbar = document.createElement("div");
|
|
15530
15553
|
toolbar.className = "db-query-history-toolbar";
|
|
15531
15554
|
const refreshBtn = document.createElement("button");
|
|
@@ -15559,7 +15582,7 @@ ${frontmatter.yaml}
|
|
|
15559
15582
|
detailPlaceholder.textContent = text3().history.selectPlaceholder;
|
|
15560
15583
|
detailCol.appendChild(detailPlaceholder);
|
|
15561
15584
|
body.append(listCol, detailCol);
|
|
15562
|
-
|
|
15585
|
+
el2.append(toolbar, body);
|
|
15563
15586
|
let entries = [];
|
|
15564
15587
|
const expandedIds = /* @__PURE__ */ new Set();
|
|
15565
15588
|
let clearConfirmTimer = null;
|
|
@@ -15967,7 +15990,7 @@ ${frontmatter.yaml}
|
|
|
15967
15990
|
}
|
|
15968
15991
|
}
|
|
15969
15992
|
}
|
|
15970
|
-
return { el, refresh, clear, localize };
|
|
15993
|
+
return { el: el2, refresh, clear, localize };
|
|
15971
15994
|
}
|
|
15972
15995
|
function formatTime(iso) {
|
|
15973
15996
|
try {
|
|
@@ -15983,17 +16006,17 @@ ${frontmatter.yaml}
|
|
|
15983
16006
|
function isBinaryItem(item) {
|
|
15984
16007
|
return typeof item === "object" && item !== null && "binaryBase64" in item;
|
|
15985
16008
|
}
|
|
15986
|
-
function renderItemInto(
|
|
15987
|
-
|
|
16009
|
+
function renderItemInto(el2, item, binaryBadge) {
|
|
16010
|
+
el2.textContent = "";
|
|
15988
16011
|
if (isBinaryItem(item)) {
|
|
15989
16012
|
const badge = document.createElement("span");
|
|
15990
16013
|
badge.className = "redis-binary-badge";
|
|
15991
16014
|
badge.textContent = binaryBadge;
|
|
15992
|
-
|
|
15993
|
-
|
|
16015
|
+
el2.appendChild(badge);
|
|
16016
|
+
el2.appendChild(document.createTextNode(item.binaryBase64));
|
|
15994
16017
|
return;
|
|
15995
16018
|
}
|
|
15996
|
-
|
|
16019
|
+
el2.textContent = item;
|
|
15997
16020
|
}
|
|
15998
16021
|
function createRedisExplorer(callbacks = {}) {
|
|
15999
16022
|
const text3 = () => (callbacks.getText?.() ?? dbText("en")).explorer;
|
|
@@ -17207,8 +17230,8 @@ ${frontmatter.yaml}
|
|
|
17207
17230
|
function isAbortError(err) {
|
|
17208
17231
|
return err instanceof DOMException && err.name === "AbortError";
|
|
17209
17232
|
}
|
|
17210
|
-
function setExplorerFolderIcon(
|
|
17211
|
-
|
|
17233
|
+
function setExplorerFolderIcon(el2, collapsed) {
|
|
17234
|
+
el2.innerHTML = iconSvg(
|
|
17212
17235
|
collapsed ? "octicon-file-directory-fill" : "octicon-file-directory-open-fill",
|
|
17213
17236
|
collapsed ? FOLDER_ICON_PATHS.closed : FOLDER_ICON_PATHS.open
|
|
17214
17237
|
);
|
|
@@ -17767,12 +17790,12 @@ ${frontmatter.yaml}
|
|
|
17767
17790
|
actions.className = "s3-preview-actions";
|
|
17768
17791
|
if (currentDbId && currentBucket) {
|
|
17769
17792
|
const rawUrl = buildS3RawUrl(currentDbId, currentBucket, object.key);
|
|
17770
|
-
const
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17793
|
+
const open2 = document.createElement("a");
|
|
17794
|
+
open2.className = "db-btn db-btn-sm";
|
|
17795
|
+
open2.href = rawUrl;
|
|
17796
|
+
open2.target = "_blank";
|
|
17797
|
+
open2.rel = "noreferrer";
|
|
17798
|
+
open2.textContent = text3().openRaw;
|
|
17776
17799
|
const download = document.createElement("a");
|
|
17777
17800
|
download.className = "db-btn db-btn-sm";
|
|
17778
17801
|
download.href = rawUrl;
|
|
@@ -17795,7 +17818,7 @@ ${frontmatter.yaml}
|
|
|
17795
17818
|
copy.textContent = text3().copyFailed;
|
|
17796
17819
|
}
|
|
17797
17820
|
});
|
|
17798
|
-
actions.append(
|
|
17821
|
+
actions.append(open2, download, copy);
|
|
17799
17822
|
if (sourceDisplayKind(object.key) === "text") {
|
|
17800
17823
|
const editBtn = mkBtn(tCommon().edit, "db-btn db-btn-sm");
|
|
17801
17824
|
editBtn.addEventListener("click", () => void startObjectEdit(object));
|
|
@@ -17922,8 +17945,8 @@ ${frontmatter.yaml}
|
|
|
17922
17945
|
function indentPad(depth) {
|
|
17923
17946
|
return `${12 + depth * 14}px`;
|
|
17924
17947
|
}
|
|
17925
|
-
function setExplorerChevron(
|
|
17926
|
-
|
|
17948
|
+
function setExplorerChevron(el2) {
|
|
17949
|
+
el2.innerHTML = `<svg class="octicon octicon-chevron-down" viewBox="0 0 12 12" width="12" height="12" fill="currentColor" aria-hidden="true"><path fill="currentColor" d="${CHEVRON_DOWN_12_PATH}"></path></svg>`;
|
|
17927
17950
|
}
|
|
17928
17951
|
function resetExplorer() {
|
|
17929
17952
|
explorerAbort?.abort();
|
|
@@ -17951,11 +17974,11 @@ ${frontmatter.yaml}
|
|
|
17951
17974
|
return await res.json();
|
|
17952
17975
|
}
|
|
17953
17976
|
function makeTreeMessageRow(cls, depth, text4) {
|
|
17954
|
-
const
|
|
17955
|
-
|
|
17956
|
-
|
|
17957
|
-
|
|
17958
|
-
return
|
|
17977
|
+
const el2 = document.createElement("div");
|
|
17978
|
+
el2.className = cls;
|
|
17979
|
+
el2.style.setProperty("--lvl-pad", indentPad(depth));
|
|
17980
|
+
el2.textContent = text4;
|
|
17981
|
+
return el2;
|
|
17959
17982
|
}
|
|
17960
17983
|
function createExplorerFileRow(object, depth) {
|
|
17961
17984
|
objectsByKey.set(object.key, object);
|
|
@@ -18422,9 +18445,9 @@ ${frontmatter.yaml}
|
|
|
18422
18445
|
// web-src/views/database/schema-view.ts
|
|
18423
18446
|
function createSchemaView(deps = {}) {
|
|
18424
18447
|
const text3 = () => deps.getText?.() ?? dbText("en");
|
|
18425
|
-
const
|
|
18426
|
-
|
|
18427
|
-
|
|
18448
|
+
const el2 = document.createElement("div");
|
|
18449
|
+
el2.className = "db-schema-view";
|
|
18450
|
+
el2.hidden = true;
|
|
18428
18451
|
let refreshBusy = false;
|
|
18429
18452
|
let refreshBtn = null;
|
|
18430
18453
|
let refreshLabel = null;
|
|
@@ -18446,8 +18469,8 @@ ${frontmatter.yaml}
|
|
|
18446
18469
|
function render(table2, columns, indexes, extra) {
|
|
18447
18470
|
lastArgs = { table: table2, columns, indexes, extra };
|
|
18448
18471
|
const t2 = text3().schema;
|
|
18449
|
-
|
|
18450
|
-
|
|
18472
|
+
el2.hidden = false;
|
|
18473
|
+
el2.innerHTML = "";
|
|
18451
18474
|
const header = document.createElement("div");
|
|
18452
18475
|
header.className = "db-schema-header";
|
|
18453
18476
|
const headerTitle = document.createElement("span");
|
|
@@ -18473,11 +18496,11 @@ ${frontmatter.yaml}
|
|
|
18473
18496
|
refreshBtn = null;
|
|
18474
18497
|
refreshLabel = null;
|
|
18475
18498
|
}
|
|
18476
|
-
|
|
18499
|
+
el2.appendChild(header);
|
|
18477
18500
|
const colSectionHeader = document.createElement("div");
|
|
18478
18501
|
colSectionHeader.className = "db-schema-section-header";
|
|
18479
18502
|
colSectionHeader.textContent = t2.columns;
|
|
18480
|
-
|
|
18503
|
+
el2.appendChild(colSectionHeader);
|
|
18481
18504
|
const colTable = document.createElement("table");
|
|
18482
18505
|
colTable.className = "db-schema-table";
|
|
18483
18506
|
const thead = document.createElement("thead");
|
|
@@ -18520,13 +18543,13 @@ ${frontmatter.yaml}
|
|
|
18520
18543
|
tbody.appendChild(tr);
|
|
18521
18544
|
}
|
|
18522
18545
|
colTable.append(thead, tbody);
|
|
18523
|
-
|
|
18546
|
+
el2.appendChild(colTable);
|
|
18524
18547
|
const fks = extra?.foreignKeys?.filter((fk) => fk.fromTable === table2);
|
|
18525
18548
|
if (fks && fks.length > 0) {
|
|
18526
18549
|
const fkHeader = document.createElement("div");
|
|
18527
18550
|
fkHeader.className = "db-schema-section-header";
|
|
18528
18551
|
fkHeader.textContent = t2.foreignKeys;
|
|
18529
|
-
|
|
18552
|
+
el2.appendChild(fkHeader);
|
|
18530
18553
|
const fkTable = document.createElement("table");
|
|
18531
18554
|
fkTable.className = "db-schema-table";
|
|
18532
18555
|
const fkThead = document.createElement("thead");
|
|
@@ -18550,14 +18573,14 @@ ${frontmatter.yaml}
|
|
|
18550
18573
|
fkTbody.appendChild(tr);
|
|
18551
18574
|
}
|
|
18552
18575
|
fkTable.append(fkThead, fkTbody);
|
|
18553
|
-
|
|
18576
|
+
el2.appendChild(fkTable);
|
|
18554
18577
|
}
|
|
18555
18578
|
const tableIndexes = indexes.filter((idx) => idx.table === table2);
|
|
18556
18579
|
if (tableIndexes.length > 0) {
|
|
18557
18580
|
const idxHeader = document.createElement("div");
|
|
18558
18581
|
idxHeader.className = "db-schema-section-header";
|
|
18559
18582
|
idxHeader.textContent = t2.indexes;
|
|
18560
|
-
|
|
18583
|
+
el2.appendChild(idxHeader);
|
|
18561
18584
|
const idxTable = document.createElement("table");
|
|
18562
18585
|
idxTable.className = "db-schema-table";
|
|
18563
18586
|
const idxThead = document.createElement("thead");
|
|
@@ -18581,14 +18604,14 @@ ${frontmatter.yaml}
|
|
|
18581
18604
|
idxTbody.appendChild(tr);
|
|
18582
18605
|
}
|
|
18583
18606
|
idxTable.append(idxThead, idxTbody);
|
|
18584
|
-
|
|
18607
|
+
el2.appendChild(idxTable);
|
|
18585
18608
|
}
|
|
18586
18609
|
const triggers = extra?.triggers;
|
|
18587
18610
|
if (triggers && triggers.length > 0) {
|
|
18588
18611
|
const trigHeader = document.createElement("div");
|
|
18589
18612
|
trigHeader.className = "db-schema-section-header";
|
|
18590
18613
|
trigHeader.textContent = t2.triggers;
|
|
18591
|
-
|
|
18614
|
+
el2.appendChild(trigHeader);
|
|
18592
18615
|
for (const trig of triggers) {
|
|
18593
18616
|
const trigBlock = document.createElement("div");
|
|
18594
18617
|
trigBlock.className = "db-schema-trigger-block";
|
|
@@ -18599,7 +18622,7 @@ ${frontmatter.yaml}
|
|
|
18599
18622
|
trigPre.className = "db-schema-ddl-pre";
|
|
18600
18623
|
trigPre.textContent = trig.sql;
|
|
18601
18624
|
trigBlock.append(trigName, trigPre);
|
|
18602
|
-
|
|
18625
|
+
el2.appendChild(trigBlock);
|
|
18603
18626
|
}
|
|
18604
18627
|
}
|
|
18605
18628
|
const ddl = extra?.ddl;
|
|
@@ -18607,7 +18630,7 @@ ${frontmatter.yaml}
|
|
|
18607
18630
|
const ddlHeader = document.createElement("div");
|
|
18608
18631
|
ddlHeader.className = "db-schema-section-header";
|
|
18609
18632
|
ddlHeader.textContent = t2.ddl;
|
|
18610
|
-
|
|
18633
|
+
el2.appendChild(ddlHeader);
|
|
18611
18634
|
const ddlWrap = document.createElement("div");
|
|
18612
18635
|
ddlWrap.className = "db-schema-ddl-wrap";
|
|
18613
18636
|
const copyBtn = document.createElement("button");
|
|
@@ -18630,22 +18653,22 @@ ${frontmatter.yaml}
|
|
|
18630
18653
|
ddlPre.className = "db-schema-ddl-pre";
|
|
18631
18654
|
ddlPre.textContent = ddl;
|
|
18632
18655
|
ddlWrap.append(copyBtn, ddlPre);
|
|
18633
|
-
|
|
18656
|
+
el2.appendChild(ddlWrap);
|
|
18634
18657
|
}
|
|
18635
18658
|
}
|
|
18636
18659
|
function clear() {
|
|
18637
|
-
|
|
18638
|
-
|
|
18660
|
+
el2.hidden = true;
|
|
18661
|
+
el2.innerHTML = "";
|
|
18639
18662
|
lastArgs = null;
|
|
18640
18663
|
refreshBtn = null;
|
|
18641
18664
|
refreshLabel = null;
|
|
18642
18665
|
refreshBusy = false;
|
|
18643
18666
|
}
|
|
18644
18667
|
function localize() {
|
|
18645
|
-
if (!lastArgs ||
|
|
18668
|
+
if (!lastArgs || el2.hidden) return;
|
|
18646
18669
|
render(lastArgs.table, lastArgs.columns, lastArgs.indexes, lastArgs.extra);
|
|
18647
18670
|
}
|
|
18648
|
-
return { el, render, clear, localize, setRefreshBusy };
|
|
18671
|
+
return { el: el2, render, clear, localize, setRefreshBusy };
|
|
18649
18672
|
}
|
|
18650
18673
|
|
|
18651
18674
|
// web-src/views/database/session-log.ts
|
|
@@ -18688,8 +18711,8 @@ ${frontmatter.yaml}
|
|
|
18688
18711
|
// web-src/views/database/session-log-view.ts
|
|
18689
18712
|
function createSessionLogView(callbacks) {
|
|
18690
18713
|
const text3 = () => callbacks.getText?.() ?? dbText("en");
|
|
18691
|
-
const
|
|
18692
|
-
|
|
18714
|
+
const el2 = document.createElement("div");
|
|
18715
|
+
el2.className = "db-session-log";
|
|
18693
18716
|
const toolbar = document.createElement("div");
|
|
18694
18717
|
toolbar.className = "db-session-log-toolbar";
|
|
18695
18718
|
const followBtn = document.createElement("button");
|
|
@@ -18718,7 +18741,7 @@ ${frontmatter.yaml}
|
|
|
18718
18741
|
placeholder.textContent = text3().sessionLog.selectPlaceholder;
|
|
18719
18742
|
detailCol.appendChild(placeholder);
|
|
18720
18743
|
body.append(listCol, detailCol);
|
|
18721
|
-
|
|
18744
|
+
el2.append(toolbar, body);
|
|
18722
18745
|
let selectedId = null;
|
|
18723
18746
|
const rowById = /* @__PURE__ */ new Map();
|
|
18724
18747
|
let autoFollow = true;
|
|
@@ -18906,7 +18929,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
18906
18929
|
placeholder.textContent = text3().sessionLog.selectPlaceholder;
|
|
18907
18930
|
render();
|
|
18908
18931
|
}
|
|
18909
|
-
return { el, clear, localize };
|
|
18932
|
+
return { el: el2, clear, localize };
|
|
18910
18933
|
}
|
|
18911
18934
|
function formatTime2(timestamp) {
|
|
18912
18935
|
const d2 = new Date(timestamp);
|
|
@@ -18944,8 +18967,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
18944
18967
|
const note = s2.note ? ` — ${s2.note}` : "";
|
|
18945
18968
|
return text3().snapshot.label(date, s2.tables.length, note);
|
|
18946
18969
|
};
|
|
18947
|
-
const
|
|
18948
|
-
|
|
18970
|
+
const el2 = document.createElement("div");
|
|
18971
|
+
el2.className = "db-snapshot-view";
|
|
18949
18972
|
const guide = document.createElement("div");
|
|
18950
18973
|
guide.className = "db-snapshot-guide";
|
|
18951
18974
|
const guideTitle = document.createElement("div");
|
|
@@ -19039,7 +19062,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
19039
19062
|
rightPane.className = "db-snapshot-right-pane";
|
|
19040
19063
|
splitContainer.append(leftPane, rightPane);
|
|
19041
19064
|
mainArea.appendChild(splitContainer);
|
|
19042
|
-
|
|
19065
|
+
el2.append(guide, toolbar, progressArea, tableSelector, mainArea);
|
|
19043
19066
|
let snapshots = [];
|
|
19044
19067
|
let currentDiff = null;
|
|
19045
19068
|
let disposed = false;
|
|
@@ -19717,8 +19740,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
19717
19740
|
threshold: 0
|
|
19718
19741
|
}
|
|
19719
19742
|
);
|
|
19720
|
-
for (const
|
|
19721
|
-
observer.observe(
|
|
19743
|
+
for (const el3 of section2.querySelectorAll(".db-snapshot-diff-table")) {
|
|
19744
|
+
observer.observe(el3);
|
|
19722
19745
|
}
|
|
19723
19746
|
section2.__tocObserver = observer;
|
|
19724
19747
|
rightPane.appendChild(section2);
|
|
@@ -19877,7 +19900,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
19877
19900
|
}
|
|
19878
19901
|
}
|
|
19879
19902
|
async function editNote(snapshotId, currentNote) {
|
|
19880
|
-
const existing =
|
|
19903
|
+
const existing = el2.querySelector(".db-snapshot-inline-dialog");
|
|
19881
19904
|
if (existing) existing.remove();
|
|
19882
19905
|
const dialog = document.createElement("div");
|
|
19883
19906
|
dialog.className = "db-snapshot-inline-dialog";
|
|
@@ -19911,7 +19934,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
19911
19934
|
});
|
|
19912
19935
|
dialog.append(input2, saveBtn, cancelDlgBtn);
|
|
19913
19936
|
const item = Array.from(
|
|
19914
|
-
|
|
19937
|
+
el2.querySelectorAll(".db-snapshot-item")
|
|
19915
19938
|
).find((node) => node.dataset.snapshotId === snapshotId);
|
|
19916
19939
|
if (item) {
|
|
19917
19940
|
item.after(dialog);
|
|
@@ -20040,7 +20063,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20040
20063
|
await showDiffInline(target.before, target.after);
|
|
20041
20064
|
}
|
|
20042
20065
|
return {
|
|
20043
|
-
el,
|
|
20066
|
+
el: el2,
|
|
20044
20067
|
refresh,
|
|
20045
20068
|
handleSse,
|
|
20046
20069
|
dispose,
|
|
@@ -20067,8 +20090,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20067
20090
|
function createTableGrid(callbacks, options = {}) {
|
|
20068
20091
|
const embedded = options.embedded === true;
|
|
20069
20092
|
const text3 = () => callbacks.getText?.() ?? dbText("en");
|
|
20070
|
-
const
|
|
20071
|
-
|
|
20093
|
+
const el2 = document.createElement("div");
|
|
20094
|
+
el2.className = "db-grid";
|
|
20072
20095
|
const filterBar = document.createElement("div");
|
|
20073
20096
|
filterBar.className = "db-grid-filter-bar";
|
|
20074
20097
|
const filterIcon = document.createElement("span");
|
|
@@ -20243,9 +20266,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20243
20266
|
detailResize.addEventListener("mousedown", startDetailResize);
|
|
20244
20267
|
detailPanel.appendChild(detailResize);
|
|
20245
20268
|
viewport.append(spacer, body, filteredEmpty);
|
|
20246
|
-
|
|
20269
|
+
el2.append(filterBar, headerWrap, filterRowWrap, viewport, detailPanel);
|
|
20247
20270
|
function panelMaxHeight() {
|
|
20248
|
-
const containerH =
|
|
20271
|
+
const containerH = el2.clientHeight || window.innerHeight;
|
|
20249
20272
|
return Math.max(
|
|
20250
20273
|
DETAIL_PANEL_MIN_HEIGHT + 1,
|
|
20251
20274
|
containerH - PANEL_MAX_RESERVE
|
|
@@ -20383,7 +20406,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20383
20406
|
relatedPanel.className = "db-related-panel";
|
|
20384
20407
|
relatedPanel.hidden = true;
|
|
20385
20408
|
relatedPanel.style.height = `${relatedHeight}px`;
|
|
20386
|
-
|
|
20409
|
+
el2.appendChild(relatedPanel);
|
|
20387
20410
|
}
|
|
20388
20411
|
const colWidths = /* @__PURE__ */ new Map();
|
|
20389
20412
|
let activeResize = null;
|
|
@@ -21611,7 +21634,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
21611
21634
|
if (!statusEl) {
|
|
21612
21635
|
statusEl = document.createElement("div");
|
|
21613
21636
|
statusEl.className = "db-grid-status";
|
|
21614
|
-
|
|
21637
|
+
el2.appendChild(statusEl);
|
|
21615
21638
|
}
|
|
21616
21639
|
const t2 = text3().grid;
|
|
21617
21640
|
const parts = [t2.statusRows(totalRows.toLocaleString())];
|
|
@@ -21636,7 +21659,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
21636
21659
|
statusEl = document.createElement("div");
|
|
21637
21660
|
statusEl.className = "db-grid-status db-pane-error";
|
|
21638
21661
|
statusEl.textContent = message;
|
|
21639
|
-
|
|
21662
|
+
el2.appendChild(statusEl);
|
|
21640
21663
|
}
|
|
21641
21664
|
function load(table2, initialData) {
|
|
21642
21665
|
clear();
|
|
@@ -21857,12 +21880,12 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
21857
21880
|
discardBtn.disabled = count === 0;
|
|
21858
21881
|
notifyEditableIfChanged();
|
|
21859
21882
|
}
|
|
21860
|
-
function setControlVisibility(
|
|
21861
|
-
|
|
21862
|
-
if ("tabIndex" in
|
|
21863
|
-
|
|
21883
|
+
function setControlVisibility(el3, visible) {
|
|
21884
|
+
el3.style.visibility = visible ? "" : "hidden";
|
|
21885
|
+
if ("tabIndex" in el3) {
|
|
21886
|
+
el3.tabIndex = visible ? 0 : -1;
|
|
21864
21887
|
}
|
|
21865
|
-
|
|
21888
|
+
el3.setAttribute("aria-hidden", visible ? "false" : "true");
|
|
21866
21889
|
}
|
|
21867
21890
|
const editableListeners = /* @__PURE__ */ new Set();
|
|
21868
21891
|
const editModeListeners = /* @__PURE__ */ new Set();
|
|
@@ -22018,7 +22041,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22018
22041
|
embeddedGrid?.refreshForeignKeys();
|
|
22019
22042
|
}
|
|
22020
22043
|
return {
|
|
22021
|
-
el,
|
|
22044
|
+
el: el2,
|
|
22022
22045
|
load,
|
|
22023
22046
|
refresh: refreshCurrentTable,
|
|
22024
22047
|
showError,
|
|
@@ -22078,9 +22101,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22078
22101
|
filterClear.innerHTML = iconSvg("octicon-x", X_16_PATH);
|
|
22079
22102
|
filterClear.hidden = true;
|
|
22080
22103
|
filterWrap.append(filterInput, filterClear);
|
|
22081
|
-
const
|
|
22082
|
-
|
|
22083
|
-
wrapper.append(filterWrap,
|
|
22104
|
+
const el2 = document.createElement("div");
|
|
22105
|
+
el2.className = "db-table-list";
|
|
22106
|
+
wrapper.append(filterWrap, el2);
|
|
22084
22107
|
let activeTable = null;
|
|
22085
22108
|
let allTables = [];
|
|
22086
22109
|
const expandedTables = /* @__PURE__ */ new Set();
|
|
@@ -22089,7 +22112,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22089
22112
|
let contextMenuClick = null;
|
|
22090
22113
|
let contextMenuKeyDown = null;
|
|
22091
22114
|
let contextMenuTimer = null;
|
|
22092
|
-
function
|
|
22115
|
+
function closeContextMenu2() {
|
|
22093
22116
|
if (contextMenuTimer) {
|
|
22094
22117
|
clearTimeout(contextMenuTimer);
|
|
22095
22118
|
contextMenuTimer = null;
|
|
@@ -22107,9 +22130,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22107
22130
|
contextMenu = null;
|
|
22108
22131
|
}
|
|
22109
22132
|
}
|
|
22110
|
-
function
|
|
22133
|
+
function showContextMenu2(e2, tableName) {
|
|
22111
22134
|
e2.preventDefault();
|
|
22112
|
-
|
|
22135
|
+
closeContextMenu2();
|
|
22113
22136
|
const menu = document.createElement("div");
|
|
22114
22137
|
menu.className = "db-context-menu";
|
|
22115
22138
|
menu.style.position = "absolute";
|
|
@@ -22150,7 +22173,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22150
22173
|
row.textContent = item.label;
|
|
22151
22174
|
row.addEventListener("click", () => {
|
|
22152
22175
|
item.action();
|
|
22153
|
-
|
|
22176
|
+
closeContextMenu2();
|
|
22154
22177
|
});
|
|
22155
22178
|
menu.appendChild(row);
|
|
22156
22179
|
}
|
|
@@ -22158,13 +22181,13 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22158
22181
|
contextMenu = menu;
|
|
22159
22182
|
const onDocClick = (ev) => {
|
|
22160
22183
|
if (!menu.contains(ev.target)) {
|
|
22161
|
-
|
|
22184
|
+
closeContextMenu2();
|
|
22162
22185
|
}
|
|
22163
22186
|
};
|
|
22164
22187
|
const onKeyDown = (ev) => {
|
|
22165
22188
|
if (isImeComposing(ev)) return;
|
|
22166
22189
|
if (ev.key === "Escape") {
|
|
22167
|
-
|
|
22190
|
+
closeContextMenu2();
|
|
22168
22191
|
}
|
|
22169
22192
|
};
|
|
22170
22193
|
contextMenuClick = onDocClick;
|
|
@@ -22246,7 +22269,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22246
22269
|
filterInput.focus();
|
|
22247
22270
|
}
|
|
22248
22271
|
function renderFiltered(tables, filter) {
|
|
22249
|
-
|
|
22272
|
+
el2.innerHTML = "";
|
|
22250
22273
|
syncFilterClearButton();
|
|
22251
22274
|
const filtered = filter ? tables.filter(
|
|
22252
22275
|
(t2) => t2.name.toLowerCase().includes(filter.toLowerCase())
|
|
@@ -22268,7 +22291,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22268
22291
|
actions.appendChild(clear);
|
|
22269
22292
|
empty.appendChild(actions);
|
|
22270
22293
|
}
|
|
22271
|
-
|
|
22294
|
+
el2.appendChild(empty);
|
|
22272
22295
|
return;
|
|
22273
22296
|
}
|
|
22274
22297
|
const groups = { table: [], view: [] };
|
|
@@ -22280,7 +22303,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22280
22303
|
const header = document.createElement("div");
|
|
22281
22304
|
header.className = "db-table-group-header";
|
|
22282
22305
|
header.textContent = type === "view" ? "Views" : "Tables";
|
|
22283
|
-
|
|
22306
|
+
el2.appendChild(header);
|
|
22284
22307
|
for (const table2 of items) {
|
|
22285
22308
|
const node = document.createElement("div");
|
|
22286
22309
|
node.className = "db-table-node";
|
|
@@ -22329,10 +22352,10 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22329
22352
|
);
|
|
22330
22353
|
row.addEventListener(
|
|
22331
22354
|
"contextmenu",
|
|
22332
|
-
(e2) =>
|
|
22355
|
+
(e2) => showContextMenu2(e2, table2.name)
|
|
22333
22356
|
);
|
|
22334
22357
|
node.append(row, children);
|
|
22335
|
-
|
|
22358
|
+
el2.appendChild(node);
|
|
22336
22359
|
}
|
|
22337
22360
|
}
|
|
22338
22361
|
}
|
|
@@ -22345,7 +22368,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22345
22368
|
}
|
|
22346
22369
|
columnCache.clear();
|
|
22347
22370
|
activeTable = null;
|
|
22348
|
-
|
|
22371
|
+
closeContextMenu2();
|
|
22349
22372
|
filterInput.value = "";
|
|
22350
22373
|
renderFiltered(tables, "");
|
|
22351
22374
|
}
|
|
@@ -22356,7 +22379,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22356
22379
|
filterClear.addEventListener("click", clearFilter);
|
|
22357
22380
|
function setActive(table2) {
|
|
22358
22381
|
activeTable = table2;
|
|
22359
|
-
|
|
22382
|
+
el2.querySelectorAll(".db-table-item").forEach((item) => {
|
|
22360
22383
|
item.classList.toggle("active", item.dataset.table === table2);
|
|
22361
22384
|
});
|
|
22362
22385
|
}
|
|
@@ -22364,7 +22387,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22364
22387
|
allTables = allTables.map(
|
|
22365
22388
|
(entry) => entry.name === table2 ? { ...entry, rowCount } : entry
|
|
22366
22389
|
);
|
|
22367
|
-
for (const node of
|
|
22390
|
+
for (const node of el2.querySelectorAll(".db-table-node")) {
|
|
22368
22391
|
if (node.dataset.table !== table2) continue;
|
|
22369
22392
|
const count = node.querySelector(".db-table-count");
|
|
22370
22393
|
if (count)
|
|
@@ -22372,7 +22395,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22372
22395
|
}
|
|
22373
22396
|
}
|
|
22374
22397
|
function dispose() {
|
|
22375
|
-
|
|
22398
|
+
closeContextMenu2();
|
|
22376
22399
|
allTables = [];
|
|
22377
22400
|
expandedTables.clear();
|
|
22378
22401
|
columnCache.clear();
|
|
@@ -25234,11 +25257,11 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25234
25257
|
return !!text3 && !/\S/.test(text3);
|
|
25235
25258
|
}
|
|
25236
25259
|
function suppressWhitespaceOnlyInlineHighlights(root) {
|
|
25237
|
-
root.querySelectorAll("ins, del").forEach((
|
|
25238
|
-
if (!isWhitespaceOnlyInlineHighlight(
|
|
25239
|
-
const parent =
|
|
25260
|
+
root.querySelectorAll("ins, del").forEach((el2) => {
|
|
25261
|
+
if (!isWhitespaceOnlyInlineHighlight(el2.textContent)) return;
|
|
25262
|
+
const parent = el2.parentNode;
|
|
25240
25263
|
if (!parent) return;
|
|
25241
|
-
parent.replaceChild(document.createTextNode(
|
|
25264
|
+
parent.replaceChild(document.createTextNode(el2.textContent || ""), el2);
|
|
25242
25265
|
});
|
|
25243
25266
|
}
|
|
25244
25267
|
|
|
@@ -25365,12 +25388,12 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25365
25388
|
button.innerHTML = expanded ? iconSvg("octicon-fold", COLLAPSE_ALL_16_PATHS) : iconSvg("octicon-unfold", EXPAND_ALL_16_PATHS);
|
|
25366
25389
|
}
|
|
25367
25390
|
function setProjectBranch(branch) {
|
|
25368
|
-
const
|
|
25369
|
-
if (!
|
|
25370
|
-
|
|
25371
|
-
const name =
|
|
25391
|
+
const el2 = document.querySelector("#project-branch");
|
|
25392
|
+
if (!el2) return;
|
|
25393
|
+
el2.hidden = !branch;
|
|
25394
|
+
const name = el2.querySelector(".project-branch-name");
|
|
25372
25395
|
if (name) name.textContent = branch;
|
|
25373
|
-
|
|
25396
|
+
el2.title = branch ? `Current branch: ${branch}` : "";
|
|
25374
25397
|
}
|
|
25375
25398
|
let metaFilesForViewedProgress = [];
|
|
25376
25399
|
function viewedProgressFor(files) {
|
|
@@ -25487,36 +25510,36 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25487
25510
|
return true;
|
|
25488
25511
|
}
|
|
25489
25512
|
function renderMeta(meta) {
|
|
25490
|
-
const
|
|
25513
|
+
const el2 = $("#meta");
|
|
25491
25514
|
if (!meta) {
|
|
25492
|
-
|
|
25515
|
+
el2.textContent = "";
|
|
25493
25516
|
metaFilesForViewedProgress = [];
|
|
25494
25517
|
return;
|
|
25495
25518
|
}
|
|
25496
25519
|
setProjectName(meta.project || "");
|
|
25497
25520
|
setProjectBranch(meta.branch || "");
|
|
25498
25521
|
metaFilesForViewedProgress = meta.files || [];
|
|
25499
|
-
|
|
25522
|
+
el2.innerHTML = "";
|
|
25500
25523
|
const text3 = diffText();
|
|
25501
25524
|
if (meta.error) {
|
|
25502
25525
|
const error2 = document.createElement("span");
|
|
25503
25526
|
error2.className = "chip chip-error";
|
|
25504
25527
|
error2.textContent = meta.error;
|
|
25505
|
-
|
|
25528
|
+
el2.appendChild(error2);
|
|
25506
25529
|
}
|
|
25507
25530
|
if (meta.totals) {
|
|
25508
25531
|
const files = document.createElement("span");
|
|
25509
25532
|
files.className = "chip chip-files";
|
|
25510
25533
|
files.textContent = text3.files(meta.totals.files);
|
|
25511
|
-
|
|
25534
|
+
el2.appendChild(files);
|
|
25512
25535
|
const add2 = document.createElement("span");
|
|
25513
25536
|
add2.className = "chip chip-add";
|
|
25514
25537
|
add2.textContent = `+${meta.totals.additions}`;
|
|
25515
|
-
|
|
25538
|
+
el2.appendChild(add2);
|
|
25516
25539
|
const del = document.createElement("span");
|
|
25517
25540
|
del.className = "chip chip-del";
|
|
25518
25541
|
del.textContent = `−${meta.totals.deletions}`;
|
|
25519
|
-
|
|
25542
|
+
el2.appendChild(del);
|
|
25520
25543
|
}
|
|
25521
25544
|
const kinds = summarizeDiffFileKinds(meta.files);
|
|
25522
25545
|
const kindChip = (className, label, count) => {
|
|
@@ -25524,7 +25547,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25524
25547
|
const chip = document.createElement("span");
|
|
25525
25548
|
chip.className = `chip ${className}`;
|
|
25526
25549
|
chip.textContent = `${count} ${label}`;
|
|
25527
|
-
|
|
25550
|
+
el2.appendChild(chip);
|
|
25528
25551
|
};
|
|
25529
25552
|
kindChip("chip-added", text3.kindAdded, kinds.added);
|
|
25530
25553
|
kindChip("chip-deleted", text3.kindDeleted, kinds.deleted);
|
|
@@ -25542,7 +25565,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25542
25565
|
viewedProgress.viewed,
|
|
25543
25566
|
viewedProgress.total
|
|
25544
25567
|
);
|
|
25545
|
-
|
|
25568
|
+
el2.appendChild(viewed);
|
|
25546
25569
|
const nextUnviewed = document.createElement("button");
|
|
25547
25570
|
nextUnviewed.type = "button";
|
|
25548
25571
|
nextUnviewed.className = "chip chip-next-unviewed";
|
|
@@ -25553,7 +25576,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25553
25576
|
nextUnviewed.addEventListener("click", () => {
|
|
25554
25577
|
scrollToNextUnviewedFile();
|
|
25555
25578
|
});
|
|
25556
|
-
|
|
25579
|
+
el2.appendChild(nextUnviewed);
|
|
25557
25580
|
}
|
|
25558
25581
|
const u2 = document.createElement("span");
|
|
25559
25582
|
u2.className = "chip chip-updated";
|
|
@@ -25561,7 +25584,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25561
25584
|
u2.textContent = text3.updated(
|
|
25562
25585
|
(/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour12: false })
|
|
25563
25586
|
);
|
|
25564
|
-
|
|
25587
|
+
el2.appendChild(u2);
|
|
25565
25588
|
}
|
|
25566
25589
|
let SUPPRESS_SPY_UNTIL = 0;
|
|
25567
25590
|
function prefetchByPath(path) {
|
|
@@ -25683,17 +25706,17 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25683
25706
|
LOAD_QUEUE.length = 0;
|
|
25684
25707
|
ACTIVE_LOADS = 0;
|
|
25685
25708
|
}
|
|
25686
|
-
function
|
|
25709
|
+
function fileKey2(f2) {
|
|
25687
25710
|
return f2.key || f2.path;
|
|
25688
25711
|
}
|
|
25689
25712
|
function computeListSignature(files) {
|
|
25690
25713
|
return files.map(
|
|
25691
|
-
(f2) => `${
|
|
25714
|
+
(f2) => `${fileKey2(f2)}\0${f2.path}\0${f2.old_path || ""}\0${f2.status || "M"}`
|
|
25692
25715
|
).join("\n");
|
|
25693
25716
|
}
|
|
25694
25717
|
function computeCardSignature(f2) {
|
|
25695
25718
|
return [
|
|
25696
|
-
|
|
25719
|
+
fileKey2(f2),
|
|
25697
25720
|
f2.status || "M",
|
|
25698
25721
|
f2.additions || 0,
|
|
25699
25722
|
f2.deletions || 0,
|
|
@@ -25770,7 +25793,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25770
25793
|
const tmp = createPlaceholder(file);
|
|
25771
25794
|
while (tmp.firstChild) card.appendChild(tmp.firstChild);
|
|
25772
25795
|
card.dataset.path = file.path;
|
|
25773
|
-
card.dataset.key =
|
|
25796
|
+
card.dataset.key = fileKey2(file);
|
|
25774
25797
|
card.dataset.sizeClass = file.size_class || "small";
|
|
25775
25798
|
card.dataset.status = file.status || "M";
|
|
25776
25799
|
card.dataset.reqId = String(++CLIENT_REQ_SEQ);
|
|
@@ -25793,7 +25816,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25793
25816
|
renderMeta(meta);
|
|
25794
25817
|
const target = getDiffRoot?.() || $("#diff");
|
|
25795
25818
|
const empty = getEmptyPane?.() || $("#empty");
|
|
25796
|
-
const expectedKeys = newFiles.map(
|
|
25819
|
+
const expectedKeys = newFiles.map(fileKey2);
|
|
25797
25820
|
const domIntact = isDiffShellDomIntact(target, expectedKeys);
|
|
25798
25821
|
const sidebarNeedsRender = shouldRenderDiffSidebar(listSame, domIntact);
|
|
25799
25822
|
if (!newFiles.length) {
|
|
@@ -25817,11 +25840,11 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25817
25840
|
empty.classList.add("hidden");
|
|
25818
25841
|
const newCardSigs = /* @__PURE__ */ new Map();
|
|
25819
25842
|
for (const f2 of newFiles) {
|
|
25820
|
-
newCardSigs.set(
|
|
25843
|
+
newCardSigs.set(fileKey2(f2), computeCardSignature(f2));
|
|
25821
25844
|
}
|
|
25822
25845
|
const pathsUnknown = !changedPaths;
|
|
25823
25846
|
const contentMayNeedReload = !listSame || pathsUnknown || (changedPaths ? newFiles.some((file) => {
|
|
25824
|
-
const key =
|
|
25847
|
+
const key = fileKey2(file);
|
|
25825
25848
|
return prevCardSignatures.get(key) !== newCardSigs.get(key) || changedPathsCoverPath(changedPaths, file.path);
|
|
25826
25849
|
}) : false);
|
|
25827
25850
|
if (contentMayNeedReload) resetLoadScheduling();
|
|
@@ -25830,14 +25853,14 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25830
25853
|
const cardsByKey = collectDiffCardsByKey(target);
|
|
25831
25854
|
const measuredHeights = /* @__PURE__ */ new Map();
|
|
25832
25855
|
for (const f2 of newFiles) {
|
|
25833
|
-
const key =
|
|
25856
|
+
const key = fileKey2(f2);
|
|
25834
25857
|
const card = cardsByKey.get(key);
|
|
25835
25858
|
if (card && (card.classList.contains("loaded") || card.classList.contains("loading")))
|
|
25836
25859
|
measuredHeights.set(key, card.offsetHeight);
|
|
25837
25860
|
}
|
|
25838
25861
|
let sidebarNeedsStatsUpdate = false;
|
|
25839
25862
|
for (const f2 of newFiles) {
|
|
25840
|
-
const key =
|
|
25863
|
+
const key = fileKey2(f2);
|
|
25841
25864
|
const oldSig = prevCardSignatures.get(key);
|
|
25842
25865
|
const newSig = newCardSigs.get(key) ?? computeCardSignature(f2);
|
|
25843
25866
|
const sigChanged = oldSig !== newSig;
|
|
@@ -25893,7 +25916,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
25893
25916
|
const oldByKey = collectDiffCardsByKey(target);
|
|
25894
25917
|
const ordered = [];
|
|
25895
25918
|
for (const f2 of newFiles) {
|
|
25896
|
-
const key =
|
|
25919
|
+
const key = fileKey2(f2);
|
|
25897
25920
|
const old = oldByKey.get(key);
|
|
25898
25921
|
if (old) {
|
|
25899
25922
|
oldByKey.delete(key);
|
|
@@ -26851,7 +26874,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26851
26874
|
const mount = getMount();
|
|
26852
26875
|
return mount ? !mount.hidden : false;
|
|
26853
26876
|
}
|
|
26854
|
-
async function
|
|
26877
|
+
async function open2() {
|
|
26855
26878
|
const mount = getMount();
|
|
26856
26879
|
if (!mount) return;
|
|
26857
26880
|
bindOnce(mount);
|
|
@@ -26886,7 +26909,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26886
26909
|
if (!mount) return;
|
|
26887
26910
|
await load(mount);
|
|
26888
26911
|
}
|
|
26889
|
-
return { open, close, isOpen, refresh };
|
|
26912
|
+
return { open: open2, close, isOpen, refresh };
|
|
26890
26913
|
}
|
|
26891
26914
|
|
|
26892
26915
|
// web-src/views/empty-diff-pane.ts
|
|
@@ -27372,12 +27395,12 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
27372
27395
|
if (label) label.textContent = "";
|
|
27373
27396
|
}
|
|
27374
27397
|
function syncRefreshResult(result) {
|
|
27375
|
-
const
|
|
27376
|
-
if (!
|
|
27377
|
-
|
|
27378
|
-
|
|
27379
|
-
|
|
27380
|
-
|
|
27398
|
+
const el2 = result ?? activeMount.refreshResult;
|
|
27399
|
+
if (!el2) return;
|
|
27400
|
+
el2.textContent = "";
|
|
27401
|
+
el2.hidden = true;
|
|
27402
|
+
el2.classList.toggle("changed", false);
|
|
27403
|
+
el2.classList.toggle("pending", false);
|
|
27381
27404
|
}
|
|
27382
27405
|
function syncFilterClearButton(button) {
|
|
27383
27406
|
const clearButton = button ?? activeMount.filterClearButton;
|
|
@@ -27398,8 +27421,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
27398
27421
|
}
|
|
27399
27422
|
const gen = generation;
|
|
27400
27423
|
const set2 = (sel, text3) => {
|
|
27401
|
-
const
|
|
27402
|
-
if (
|
|
27424
|
+
const el2 = info.querySelector(sel);
|
|
27425
|
+
if (el2) el2.textContent = text3;
|
|
27403
27426
|
};
|
|
27404
27427
|
info.querySelector(".hci-head")?.removeAttribute("hidden");
|
|
27405
27428
|
set2(".hci-sha", commit.sha);
|
|
@@ -27935,8 +27958,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
27935
27958
|
|
|
27936
27959
|
// web-src/views/file-history-shell.ts
|
|
27937
27960
|
function removeFileHistoryShell() {
|
|
27938
|
-
document.querySelectorAll(".gdp-standalone-file-history").forEach((
|
|
27939
|
-
(
|
|
27961
|
+
document.querySelectorAll(".gdp-standalone-file-history").forEach((el2) => {
|
|
27962
|
+
(el2.closest(".gdp-repo-blob-layout") || el2).remove();
|
|
27940
27963
|
});
|
|
27941
27964
|
}
|
|
27942
27965
|
function renderFileHistoryShell(deps, route, options = {}) {
|
|
@@ -28901,6 +28924,31 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
28901
28924
|
}
|
|
28902
28925
|
]
|
|
28903
28926
|
},
|
|
28927
|
+
{
|
|
28928
|
+
title: "Worktrees",
|
|
28929
|
+
blocks: [
|
|
28930
|
+
{
|
|
28931
|
+
kind: "paragraph",
|
|
28932
|
+
text: "The Worktrees item in the header menu lists every worktree of this repository — the main one and every linked worktree — in the same three-pane shape as History: pick a worktree on the left, its changed files in the middle, the diff on the right. Running one coding agent per worktree makes that spread invisible from inside a single checkout, and this screen is where it becomes visible again. The selection lives in the URL (?wt=…&file=…), so a reload comes back to the same diff."
|
|
28933
|
+
},
|
|
28934
|
+
{
|
|
28935
|
+
kind: "paragraph",
|
|
28936
|
+
text: `Every row in the left pane answers two things. How far the branch has drifted from the base branch (how many commits ahead and behind), and whether it still merges: code-viewer runs git merge-tree without touching any working tree, so a row says either that it merges cleanly, or how many files would conflict, or that the check could not run — the last one is kept separate from the first, because "not checked" is not "safe". The middle pane then splits that worktree's files into work that is not committed yet and commits made since the branch point, with added and deleted line counts; the diff itself is rendered by the same viewer the Diff screen uses, from git run inside that worktree.`
|
|
28937
|
+
},
|
|
28938
|
+
{
|
|
28939
|
+
kind: "paragraph",
|
|
28940
|
+
text: "The banner above the cards is the one to read first. It names every file that more than one worktree is currently changing, and the same files are marked inside each card. Two agents editing the same file is invisible until one of them merges; this is where it shows up before that happens. The base branch is whatever origin/HEAD points at, falling back to main and then master; each row names the one it used."
|
|
28941
|
+
},
|
|
28942
|
+
{
|
|
28943
|
+
kind: "paragraph",
|
|
28944
|
+
text: "Create makes a worktree under .worktrees/ in the repository root. You give it a folder name and the dialog shows the exact path it will create as you type; the branch defaults to that same name, so an existing branch is checked out and otherwise a new one starts from where you are. Because that folder sits inside the repository, git reports it as untracked until you add .worktrees/ to .gitignore — the dialog keeps that note behind a ? mark, and code-viewer never edits .gitignore for you. Remove deletes the worktree's folder from disk — the dialog says so, with the full path and a note that it cannot be undone — and keeps the branch and its committed work. With uncommitted changes the dialog also shows a warning and requires a checkbox before it deletes. An entry whose folder is already gone is cleaned from git's bookkeeping instead (git worktree prune), and the dialog says how many such entries will go. Because prune silently skips locked entries and still succeeds, code-viewer checks the entry is actually gone before reporting success and explains why if it is not. The worktree this server is serving cannot be removed from here. Delete sits on its own line, away from the everyday buttons, and stays muted until you reach for it."
|
|
28945
|
+
},
|
|
28946
|
+
{
|
|
28947
|
+
kind: "paragraph",
|
|
28948
|
+
text: 'Every row carries a "…" on the right, and every action for that worktree lives in it — no button appears just because you picked a row, and the row you act on is the row you opened the menu from, whether or not it is the one being shown. "Open in a new tab" starts a second code-viewer for that worktree, because a server stays on the working tree it started in; an already-running server is reused instead of started again. Those servers outlive this one, so "Stop its server" is in the same menu — the Server group in doctor still lists them all, and `kill <pid>` works too, with the pid in ~/.cache/code-viewer/servers/. A worktree that merges cleanly also offers to copy the `git switch` / `git merge` command; code-viewer copies it and never runs it. "Copy its address" is there because a new tab can be stopped by a browser extension before it loads (Chrome reports ERR_BLOCKED_BY_CLIENT) — the address still works in another browser or from a terminal. "Open folder" only appears for worktrees inside the repository, since that is the only place code-viewer will open on your behalf.'
|
|
28949
|
+
}
|
|
28950
|
+
]
|
|
28951
|
+
},
|
|
28904
28952
|
{
|
|
28905
28953
|
title: "Environment doctor",
|
|
28906
28954
|
blocks: [
|
|
@@ -29643,6 +29691,31 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
29643
29691
|
}
|
|
29644
29692
|
]
|
|
29645
29693
|
},
|
|
29694
|
+
{
|
|
29695
|
+
title: "作業ツリー",
|
|
29696
|
+
blocks: [
|
|
29697
|
+
{
|
|
29698
|
+
kind: "paragraph",
|
|
29699
|
+
text: "ヘッダメニューの「作業ツリー」は、このリポジトリの作業ツリーを本体ぶんも含めて並べます。画面の形は履歴と同じ 3 つの列で、左で作業ツリーを選び、中央にその変更ファイル、右に差分が出ます。コーディングエージェントを作業ツリーごとに走らせると、1 つのチェックアウトの中からは全体が見えなくなります。この画面はそれを見えるようにするためのものです。選んだものは URL に載る (?wt=…&file=…) ので、読み込み直しても同じ差分に戻ります。"
|
|
29700
|
+
},
|
|
29701
|
+
{
|
|
29702
|
+
kind: "paragraph",
|
|
29703
|
+
text: "左の 1 行が答えるのは 2 つです。基準ブランチからどれだけ離れているか(進んだぶん・遅れたぶんのコミット数)。そしてまだマージできるか — 作業ツリーを一切触らない git merge-tree で試し、「そのままマージできます」「マージすると何ファイルで衝突するか」「確かめられなかった」を出し分けます。最後のものは 1 番目と混ぜません。「確かめていない」は「安全」ではないからです。中央の列は、その作業ツリーが触っているファイルを、まだコミットしていないぶんと分岐した後のコミットに分けて、追加・削除の行数つきで出します。差分そのものは Diff ビューアと同じ描画で、その作業ツリーの中で走らせた git の結果です。"
|
|
29704
|
+
},
|
|
29705
|
+
{
|
|
29706
|
+
kind: "paragraph",
|
|
29707
|
+
text: "カードの上の帯を最初に読んでください。2 本以上の作業ツリーが今まさに触っているファイルを名指しで挙げ、同じファイルは各カードの中にも印が付きます。2 つのエージェントが同じファイルを書いていることは、どちらかをマージするまで表に出ません。ここはそれが起きる前に出る場所です。基準ブランチは origin/HEAD が指す先で、無ければ main、次に master を使います。どれを使ったかは各行に出ます。"
|
|
29708
|
+
},
|
|
29709
|
+
{
|
|
29710
|
+
kind: "paragraph",
|
|
29711
|
+
text: "「作る」はリポジトリ直下の .worktrees/ の下に作業ツリーを作ります。入力するのはフォルダ名で、打つそばから作られるパスがダイアログに出ます。ブランチは同じ名前が既定で、既にあるブランチならそれを開き、無ければいまの地点から新しく作ります。この置き場所はリポジトリの中なので、.worktrees/ を .gitignore に入れるまでは git から未追跡として見えます。その案内はダイアログの「?」に入れてあり、code-viewer が .gitignore を書き換えることはしません。「削除」はその作業ツリーのフォルダをディスクから消します。ダイアログにはフルパスと「元に戻せません」が出ます。ブランチとコミット済みの内容は残します。コミットしていない変更があるときは警告が出て、チェックを入れないと削除できません。フォルダが既に無い登録は git の管理情報の掃除 (git worktree prune) になり、同じ状態の登録が他にもあれば件数を出します。prune はロックされた登録を黙って飛ばして成功を返すので、消えたことを確かめてから成功と言います (残っていれば理由つきで断ります)。このサーバが映している作業ツリーはここからは消せません。削除だけは他の操作と段を分けて置いてあり、押すまでは沈んだ字で出ます。"
|
|
29712
|
+
},
|
|
29713
|
+
{
|
|
29714
|
+
kind: "paragraph",
|
|
29715
|
+
text: "各行の右端に「…」があり、その作業ツリーへの操作は全部その中にあります。行を選んだからといってボタンが現れることはなく、操作の相手は「…」を開いた行です(いま映している行である必要はありません)。「別タブで見る」はその作業ツリーで code-viewer をもう 1 本起こします。サーバは起動したときの作業ツリーから動けないためです。既に動いているサーバがあれば使い回します。起こしたサーバはこのサーバより長く生きるので、「サーバを止める」を同じメニューに置いてあります。doctor の Server グループには変わらず一覧が出ますし、`kill <pid>` でも止まります(pid は ~/.cache/code-viewer/servers/)。そのままマージできる作業ツリーには、取り込むコマンドのコピーも出ます。コピーするだけで、code-viewer が実行することはありません。「アドレスをコピー」があるのは、開いたタブがブラウザ拡張に止められることがあるためです(Chrome は ERR_BLOCKED_BY_CLIENT と出します)。アドレスさえ手元にあれば、別のブラウザやターミナルから開けます。「フォルダを開く」はリポジトリの中にある作業ツリーにだけ出ます。code-viewer が代わりに開くのはそこまでだからです。"
|
|
29716
|
+
}
|
|
29717
|
+
]
|
|
29718
|
+
},
|
|
29646
29719
|
{
|
|
29647
29720
|
title: "環境ドクター",
|
|
29648
29721
|
blocks: [
|
|
@@ -31810,13 +31883,13 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
31810
31883
|
function clearTaskDropTargets() {
|
|
31811
31884
|
root.querySelectorAll(
|
|
31812
31885
|
".journal-task-card.drop-target, .journal-task-column.drop-target"
|
|
31813
|
-
).forEach((
|
|
31814
|
-
|
|
31886
|
+
).forEach((el2) => {
|
|
31887
|
+
el2.classList.remove("drop-target", "drop-after");
|
|
31815
31888
|
});
|
|
31816
31889
|
}
|
|
31817
31890
|
function clearTaskDragState() {
|
|
31818
|
-
root.querySelectorAll(".journal-task-card.dragging").forEach((
|
|
31819
|
-
|
|
31891
|
+
root.querySelectorAll(".journal-task-card.dragging").forEach((el2) => {
|
|
31892
|
+
el2.classList.remove("dragging");
|
|
31820
31893
|
});
|
|
31821
31894
|
stopTaskDragAutoScroll();
|
|
31822
31895
|
clearTaskDropTargets();
|
|
@@ -33110,7 +33183,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
33110
33183
|
fullLink.textContent = text3.viewAll;
|
|
33111
33184
|
settingsLink.textContent = text3.settings;
|
|
33112
33185
|
}
|
|
33113
|
-
function
|
|
33186
|
+
function open2() {
|
|
33114
33187
|
applyText();
|
|
33115
33188
|
renderContent();
|
|
33116
33189
|
popover.hidden = false;
|
|
@@ -33122,7 +33195,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
33122
33195
|
}
|
|
33123
33196
|
function toggle() {
|
|
33124
33197
|
if (isOpen()) close();
|
|
33125
|
-
else
|
|
33198
|
+
else open2();
|
|
33126
33199
|
}
|
|
33127
33200
|
trigger.addEventListener("click", toggle);
|
|
33128
33201
|
closeBtn.addEventListener("click", close);
|
|
@@ -33152,7 +33225,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
33152
33225
|
applyText();
|
|
33153
33226
|
if (isOpen()) renderContent();
|
|
33154
33227
|
}
|
|
33155
|
-
return { open, close, toggle, isOpen, localize };
|
|
33228
|
+
return { open: open2, close, toggle, isOpen, localize };
|
|
33156
33229
|
}
|
|
33157
33230
|
|
|
33158
33231
|
// web-src/views/ref-picker.ts
|
|
@@ -33669,9 +33742,9 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
33669
33742
|
syncSidebarHeaderHeight();
|
|
33670
33743
|
}
|
|
33671
33744
|
let SIDEBAR_FILES = [];
|
|
33672
|
-
function setFolderIcon(
|
|
33745
|
+
function setFolderIcon(el2, collapsed) {
|
|
33673
33746
|
const path = collapsed ? FOLDER_ICON_PATHS.closed : FOLDER_ICON_PATHS.open;
|
|
33674
|
-
|
|
33747
|
+
el2.innerHTML = '<svg class="octicon octicon-file-directory-' + (collapsed ? "fill" : "open-fill") + '" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true"><path fill="currentColor" d="' + path + '"></path></svg>';
|
|
33675
33748
|
}
|
|
33676
33749
|
function setSidebarTreeActionIcons() {
|
|
33677
33750
|
const sidebarToggle = ensureSidebarToggleButton();
|
|
@@ -34281,13 +34354,13 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
34281
34354
|
input2.toggleAttribute("aria-invalid", invalid);
|
|
34282
34355
|
input2.title = invalid ? filter.error || "invalid regular expression" : "";
|
|
34283
34356
|
const filterActive = filter.kind !== "empty" && !invalid;
|
|
34284
|
-
const
|
|
34357
|
+
const matches2 = invalid ? () => true : filter.match;
|
|
34285
34358
|
const walk = (node, depth) => {
|
|
34286
34359
|
let subtreeVisible = false;
|
|
34287
34360
|
const rows = [];
|
|
34288
34361
|
for (const item of treeNodeItems(node)) {
|
|
34289
34362
|
if (item.kind === "dir") {
|
|
34290
|
-
const dirMatches = filterActive &&
|
|
34363
|
+
const dirMatches = filterActive && matches2(item.dir.path);
|
|
34291
34364
|
const eff = dirEffectiveCollapsed(item.dir);
|
|
34292
34365
|
const expanded = !item.dir.children_omitted && !eff.lazyNotLoaded && (filterActive ? !eff.userCollapsed : !eff.effectiveCollapsed);
|
|
34293
34366
|
const child = walk(item.dir, depth + 1);
|
|
@@ -34305,7 +34378,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
34305
34378
|
subtreeVisible = subtreeVisible || visible;
|
|
34306
34379
|
} else {
|
|
34307
34380
|
const testHidden = STATE.hideTests && !isRepositorySidebarMode() && isTestPath(item.file.path || "");
|
|
34308
|
-
const visible = !testHidden &&
|
|
34381
|
+
const visible = !testHidden && matches2(item.file.path || "");
|
|
34309
34382
|
if (visible) {
|
|
34310
34383
|
rows.push({
|
|
34311
34384
|
kind: "file",
|
|
@@ -34703,19 +34776,19 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
34703
34776
|
const invalid = filter.kind === "invalid";
|
|
34704
34777
|
input2.toggleAttribute("aria-invalid", invalid);
|
|
34705
34778
|
input2.title = invalid ? filter.error || "invalid regular expression" : "";
|
|
34706
|
-
const
|
|
34779
|
+
const matches2 = invalid ? () => true : filter.match;
|
|
34707
34780
|
const filterActive = filter.kind !== "empty" && !invalid;
|
|
34708
34781
|
$$("#filelist li[data-path]").forEach((li) => {
|
|
34709
|
-
const match2 =
|
|
34782
|
+
const match2 = matches2(li.dataset.path || "");
|
|
34710
34783
|
li.classList.toggle("hidden", !match2);
|
|
34711
34784
|
});
|
|
34712
34785
|
if (!isRepositorySidebarMode()) {
|
|
34713
34786
|
document.querySelectorAll(".gdp-file-shell").forEach((card) => {
|
|
34714
|
-
const match2 =
|
|
34787
|
+
const match2 = matches2(card.dataset.path || "");
|
|
34715
34788
|
card.classList.toggle("hidden-by-filter", !match2);
|
|
34716
34789
|
});
|
|
34717
34790
|
}
|
|
34718
|
-
updateTreeDirVisibility(
|
|
34791
|
+
updateTreeDirVisibility(matches2, filterActive);
|
|
34719
34792
|
if (!isRepositorySidebarMode() && typeof applyViewedState === "function")
|
|
34720
34793
|
applyViewedState();
|
|
34721
34794
|
}
|
|
@@ -34769,6 +34842,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
34769
34842
|
const input2 = document.querySelector("#sb-filter");
|
|
34770
34843
|
if (!input2?.value) return;
|
|
34771
34844
|
input2.value = "";
|
|
34845
|
+
input2.dispatchEvent(new Event("input", { bubbles: true }));
|
|
34772
34846
|
syncSidebarFilterClearButton();
|
|
34773
34847
|
flushSidebarFilter();
|
|
34774
34848
|
applyFilter();
|
|
@@ -37242,11 +37316,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37242
37316
|
const grouped = /* @__PURE__ */ new Map();
|
|
37243
37317
|
state.items.forEach((item, index) => {
|
|
37244
37318
|
if (item.kind !== "grep") return;
|
|
37245
|
-
const
|
|
37246
|
-
|
|
37247
|
-
grouped.set(item.path,
|
|
37319
|
+
const matches2 = grouped.get(item.path) ?? [];
|
|
37320
|
+
matches2.push({ item, index });
|
|
37321
|
+
grouped.set(item.path, matches2);
|
|
37248
37322
|
});
|
|
37249
|
-
for (const [path,
|
|
37323
|
+
for (const [path, matches2] of grouped) {
|
|
37250
37324
|
const group = document.createElement("section");
|
|
37251
37325
|
group.className = "gdp-palette-file-group";
|
|
37252
37326
|
group.setAttribute("role", "group");
|
|
@@ -37259,11 +37333,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37259
37333
|
name.title = path;
|
|
37260
37334
|
const count = document.createElement("span");
|
|
37261
37335
|
count.className = "gdp-palette-file-heading-count";
|
|
37262
|
-
count.textContent = String(
|
|
37336
|
+
count.textContent = String(matches2.length);
|
|
37263
37337
|
heading2.append(name, count);
|
|
37264
37338
|
const rows = document.createElement("div");
|
|
37265
37339
|
rows.className = "gdp-palette-file-matches";
|
|
37266
|
-
for (const match2 of
|
|
37340
|
+
for (const match2 of matches2) {
|
|
37267
37341
|
rows.appendChild(
|
|
37268
37342
|
createPaletteRow(state, match2.item, match2.index, true)
|
|
37269
37343
|
);
|
|
@@ -38028,11 +38102,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38028
38102
|
return STATE.route.screen === "file" ? { path: STATE.route.path, ref: STATE.route.ref } : null;
|
|
38029
38103
|
}
|
|
38030
38104
|
function removeStandaloneSource() {
|
|
38031
|
-
document.querySelectorAll(".gdp-standalone-source").forEach((
|
|
38032
|
-
|
|
38105
|
+
document.querySelectorAll(".gdp-standalone-source").forEach((el2) => {
|
|
38106
|
+
el2.remove();
|
|
38033
38107
|
});
|
|
38034
|
-
document.querySelectorAll(".gdp-repo-blob-layout").forEach((
|
|
38035
|
-
|
|
38108
|
+
document.querySelectorAll(".gdp-repo-blob-layout").forEach((el2) => {
|
|
38109
|
+
el2.remove();
|
|
38036
38110
|
});
|
|
38037
38111
|
}
|
|
38038
38112
|
function renderSourceLoading(card, target, onCancel) {
|
|
@@ -38598,17 +38672,17 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38598
38672
|
return ranges;
|
|
38599
38673
|
}
|
|
38600
38674
|
function collectVirtualSourceSearchMatches(lines, query, max = 5e3) {
|
|
38601
|
-
const
|
|
38602
|
-
for (let index = 0; index < lines.length &&
|
|
38675
|
+
const matches2 = [];
|
|
38676
|
+
for (let index = 0; index < lines.length && matches2.length < max; index++) {
|
|
38603
38677
|
for (const range of virtualSourceSearchRanges(
|
|
38604
38678
|
lines[index] || "",
|
|
38605
38679
|
query
|
|
38606
38680
|
)) {
|
|
38607
|
-
|
|
38608
|
-
if (
|
|
38681
|
+
matches2.push({ line: index + 1, start: range.start, end: range.end });
|
|
38682
|
+
if (matches2.length >= max) break;
|
|
38609
38683
|
}
|
|
38610
38684
|
}
|
|
38611
|
-
return
|
|
38685
|
+
return matches2;
|
|
38612
38686
|
}
|
|
38613
38687
|
function appendVirtualSourceLineCode(code2, line, query, activeRange, lineNumber) {
|
|
38614
38688
|
const ranges = virtualSourceSearchRanges(line, query);
|
|
@@ -38652,7 +38726,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38652
38726
|
bar.append(input2, count, previous, next, close);
|
|
38653
38727
|
wrap.querySelector(".gdp-source-virtual-info")?.appendChild(bar);
|
|
38654
38728
|
bar.hidden = true;
|
|
38655
|
-
let
|
|
38729
|
+
let matches2 = [];
|
|
38656
38730
|
let active = -1;
|
|
38657
38731
|
let debounce = 0;
|
|
38658
38732
|
let searchVersion = 0;
|
|
@@ -38665,7 +38739,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38665
38739
|
const query = input2.value;
|
|
38666
38740
|
const version = ++searchVersion;
|
|
38667
38741
|
if (!query) {
|
|
38668
|
-
|
|
38742
|
+
matches2 = [];
|
|
38669
38743
|
active = -1;
|
|
38670
38744
|
count.textContent = "";
|
|
38671
38745
|
renderFn();
|
|
@@ -38674,20 +38748,20 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38674
38748
|
count.textContent = "Searching...";
|
|
38675
38749
|
findMatches(query).then((nextMatches) => {
|
|
38676
38750
|
if (version !== searchVersion) return;
|
|
38677
|
-
|
|
38678
|
-
active =
|
|
38679
|
-
count.textContent =
|
|
38751
|
+
matches2 = nextMatches;
|
|
38752
|
+
active = matches2.length ? Math.max(0, Math.min(active, matches2.length - 1)) : -1;
|
|
38753
|
+
count.textContent = matches2.length ? `${active + 1} / ${matches2.length}` : "0 / 0";
|
|
38680
38754
|
if (active >= 0) {
|
|
38681
38755
|
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
38682
38756
|
scroller.scrollTop = Math.max(
|
|
38683
38757
|
0,
|
|
38684
|
-
(
|
|
38758
|
+
(matches2[active].line - 1) * rowHeight - rowHeight * 3
|
|
38685
38759
|
);
|
|
38686
38760
|
}
|
|
38687
38761
|
renderFn();
|
|
38688
38762
|
}).catch(() => {
|
|
38689
38763
|
if (version !== searchVersion) return;
|
|
38690
|
-
|
|
38764
|
+
matches2 = [];
|
|
38691
38765
|
active = -1;
|
|
38692
38766
|
count.textContent = "Search failed";
|
|
38693
38767
|
renderFn();
|
|
@@ -38698,13 +38772,13 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38698
38772
|
debounce = window.setTimeout(sync, 120);
|
|
38699
38773
|
};
|
|
38700
38774
|
const move = (direction) => {
|
|
38701
|
-
if (!
|
|
38702
|
-
active = (active + direction +
|
|
38703
|
-
count.textContent = `${active + 1} / ${
|
|
38775
|
+
if (!matches2.length) return;
|
|
38776
|
+
active = (active + direction + matches2.length) % matches2.length;
|
|
38777
|
+
count.textContent = `${active + 1} / ${matches2.length}`;
|
|
38704
38778
|
const rowHeight = sourceLineScrollAmount() || VIRTUAL_SOURCE_ROW_HEIGHT;
|
|
38705
38779
|
scroller.scrollTop = Math.max(
|
|
38706
38780
|
0,
|
|
38707
|
-
(
|
|
38781
|
+
(matches2[active].line - 1) * rowHeight - rowHeight * 3
|
|
38708
38782
|
);
|
|
38709
38783
|
renderFn();
|
|
38710
38784
|
};
|
|
@@ -38733,7 +38807,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38733
38807
|
sync();
|
|
38734
38808
|
},
|
|
38735
38809
|
query: () => bar.hidden ? "" : input2.value,
|
|
38736
|
-
activeRange: () => active >= 0 ?
|
|
38810
|
+
activeRange: () => active >= 0 ? matches2[active] || null : null
|
|
38737
38811
|
};
|
|
38738
38812
|
}
|
|
38739
38813
|
function openVirtualSourceSearchFromKeyboard(targetEl) {
|
|
@@ -39100,10 +39174,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39100
39174
|
scroller.__gdpRenderVirtualSource = render;
|
|
39101
39175
|
scroller.addEventListener("scroll", schedule, { passive: true });
|
|
39102
39176
|
const findPagedMatches = async (query, matchSignal) => {
|
|
39103
|
-
const
|
|
39177
|
+
const matches2 = [];
|
|
39104
39178
|
let startLine = 1;
|
|
39105
39179
|
let done = false;
|
|
39106
|
-
while (!done &&
|
|
39180
|
+
while (!done && matches2.length < 5e3) {
|
|
39107
39181
|
const endLine = startLine + VIRTUAL_SOURCE_PAGE_SIZE - 1;
|
|
39108
39182
|
const data = await trackLoad(
|
|
39109
39183
|
fetch(buildFileRangeUrl(target, startLine, endLine), {
|
|
@@ -39118,12 +39192,12 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39118
39192
|
const lineNumber = data.start + index;
|
|
39119
39193
|
lines.set(lineNumber, lineValue);
|
|
39120
39194
|
for (const range of virtualSourceSearchRanges(lineValue, query)) {
|
|
39121
|
-
|
|
39195
|
+
matches2.push({
|
|
39122
39196
|
line: lineNumber,
|
|
39123
39197
|
start: range.start,
|
|
39124
39198
|
end: range.end
|
|
39125
39199
|
});
|
|
39126
|
-
if (
|
|
39200
|
+
if (matches2.length >= 5e3) break;
|
|
39127
39201
|
}
|
|
39128
39202
|
});
|
|
39129
39203
|
totalRows = data.complete ? Math.max(1, data.total) : Math.max(totalRows, data.total, endLine + VIRTUAL_SOURCE_PAGE_SIZE);
|
|
@@ -39135,7 +39209,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39135
39209
|
renderedStart = -1;
|
|
39136
39210
|
renderedEnd = -1;
|
|
39137
39211
|
schedule();
|
|
39138
|
-
return
|
|
39212
|
+
return matches2;
|
|
39139
39213
|
};
|
|
39140
39214
|
search = createVirtualSourceSearch(
|
|
39141
39215
|
wrap,
|
|
@@ -39313,8 +39387,8 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39313
39387
|
const repoTarget = repoFileTargetFromRoute();
|
|
39314
39388
|
setPageMode();
|
|
39315
39389
|
removeStandaloneSource();
|
|
39316
|
-
document.querySelectorAll(".gdp-repo-blob-layout").forEach((
|
|
39317
|
-
|
|
39390
|
+
document.querySelectorAll(".gdp-repo-blob-layout").forEach((el2) => {
|
|
39391
|
+
el2.remove();
|
|
39318
39392
|
});
|
|
39319
39393
|
const card = document.createElement("article");
|
|
39320
39394
|
card.className = "gdp-file-shell loaded gdp-standalone-source gdp-source-mode";
|
|
@@ -39785,13 +39859,13 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39785
39859
|
}
|
|
39786
39860
|
|
|
39787
39861
|
// web-src/core/scroll-chaining.ts
|
|
39788
|
-
function hasScrollRoom(
|
|
39789
|
-
const up = event.deltaY < 0 &&
|
|
39790
|
-
const down = event.deltaY > 0 &&
|
|
39791
|
-
const left = event.deltaX < 0 &&
|
|
39792
|
-
const right = event.deltaX > 0 &&
|
|
39862
|
+
function hasScrollRoom(el2, event) {
|
|
39863
|
+
const up = event.deltaY < 0 && el2.scrollTop > 1;
|
|
39864
|
+
const down = event.deltaY > 0 && el2.scrollHeight - el2.clientHeight - el2.scrollTop > 1;
|
|
39865
|
+
const left = event.deltaX < 0 && el2.scrollLeft > 1;
|
|
39866
|
+
const right = event.deltaX > 0 && el2.scrollWidth - el2.clientWidth - el2.scrollLeft > 1;
|
|
39793
39867
|
if (!up && !down && !left && !right) return false;
|
|
39794
|
-
const style = getComputedStyle(
|
|
39868
|
+
const style = getComputedStyle(el2);
|
|
39795
39869
|
const scrollsY = style.overflowY === "auto" || style.overflowY === "scroll";
|
|
39796
39870
|
const scrollsX = style.overflowX === "auto" || style.overflowX === "scroll";
|
|
39797
39871
|
return (up || down) && scrollsY || (left || right) && scrollsX;
|
|
@@ -39999,8 +40073,8 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39999
40073
|
return parts.join(BRANCH_KEY_SEP);
|
|
40000
40074
|
}
|
|
40001
40075
|
function createSessionBoard(deps) {
|
|
40002
|
-
const
|
|
40003
|
-
|
|
40076
|
+
const el2 = document.createElement("div");
|
|
40077
|
+
el2.className = "terminal-board";
|
|
40004
40078
|
const scopeBar = document.createElement("div");
|
|
40005
40079
|
scopeBar.className = "terminal-scope";
|
|
40006
40080
|
const scopeSelect = document.createElement("select");
|
|
@@ -40043,7 +40117,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
40043
40117
|
tree.role = "tree";
|
|
40044
40118
|
const treeEmpty = document.createElement("p");
|
|
40045
40119
|
treeEmpty.className = "terminal-empty";
|
|
40046
|
-
|
|
40120
|
+
el2.append(scopeBar, observationErrors, attentionSection, filters, tree);
|
|
40047
40121
|
let data = {
|
|
40048
40122
|
panes: null,
|
|
40049
40123
|
shells: [],
|
|
@@ -40116,12 +40190,12 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
40116
40190
|
}
|
|
40117
40191
|
const actions = document.createElement("div");
|
|
40118
40192
|
actions.className = "terminal-card-actions";
|
|
40119
|
-
const
|
|
40120
|
-
|
|
40121
|
-
|
|
40122
|
-
|
|
40123
|
-
|
|
40124
|
-
actions.appendChild(
|
|
40193
|
+
const open2 = document.createElement("button");
|
|
40194
|
+
open2.type = "button";
|
|
40195
|
+
open2.className = `terminal-card-open terminal-card-open-${row.state}`;
|
|
40196
|
+
open2.textContent = text3.openTarget;
|
|
40197
|
+
open2.addEventListener("click", () => activate(row));
|
|
40198
|
+
actions.appendChild(open2);
|
|
40125
40199
|
if (row.state === "done") {
|
|
40126
40200
|
const read = document.createElement("button");
|
|
40127
40201
|
read.type = "button";
|
|
@@ -40415,7 +40489,7 @@ ${error2.stack}` : ""}`;
|
|
|
40415
40489
|
}
|
|
40416
40490
|
render();
|
|
40417
40491
|
return {
|
|
40418
|
-
el,
|
|
40492
|
+
el: el2,
|
|
40419
40493
|
setData(next) {
|
|
40420
40494
|
data = next;
|
|
40421
40495
|
render();
|
|
@@ -40471,17 +40545,17 @@ ${error2.stack}` : ""}`;
|
|
|
40471
40545
|
previouslyFocused?.focus?.();
|
|
40472
40546
|
};
|
|
40473
40547
|
const button = (label, title2, onClick) => {
|
|
40474
|
-
const
|
|
40475
|
-
|
|
40476
|
-
|
|
40477
|
-
|
|
40478
|
-
|
|
40479
|
-
|
|
40480
|
-
|
|
40548
|
+
const el2 = document.createElement("button");
|
|
40549
|
+
el2.type = "button";
|
|
40550
|
+
el2.className = "terminal-font-btn";
|
|
40551
|
+
el2.textContent = label;
|
|
40552
|
+
el2.title = title2;
|
|
40553
|
+
el2.setAttribute("aria-label", title2);
|
|
40554
|
+
el2.addEventListener("click", (event) => {
|
|
40481
40555
|
event.stopPropagation();
|
|
40482
40556
|
onClick();
|
|
40483
40557
|
});
|
|
40484
|
-
return
|
|
40558
|
+
return el2;
|
|
40485
40559
|
};
|
|
40486
40560
|
zoomReset = button("100%", text3.zoomReset, () => viewport.reset());
|
|
40487
40561
|
actions.append(
|
|
@@ -40536,14 +40610,14 @@ ${error2.stack}` : ""}`;
|
|
|
40536
40610
|
var INLINE_IMAGE_COLS = 30;
|
|
40537
40611
|
var INLINE_IMAGE_ROWS = 8;
|
|
40538
40612
|
function createTerminalScreen(deps) {
|
|
40539
|
-
const
|
|
40540
|
-
|
|
40613
|
+
const el2 = document.createElement("div");
|
|
40614
|
+
el2.className = "terminal-pane-body";
|
|
40541
40615
|
const attachments = document.createElement("div");
|
|
40542
40616
|
attachments.className = "terminal-attachments";
|
|
40543
40617
|
attachments.hidden = true;
|
|
40544
40618
|
const screenEl = document.createElement("div");
|
|
40545
40619
|
screenEl.className = "terminal-screen";
|
|
40546
|
-
|
|
40620
|
+
el2.append(attachments, screenEl);
|
|
40547
40621
|
let term = null;
|
|
40548
40622
|
let fitAddon = null;
|
|
40549
40623
|
let source = null;
|
|
@@ -40664,13 +40738,13 @@ ${formatErrorDetail(error2)}`
|
|
|
40664
40738
|
function addAttachment(src, name, path) {
|
|
40665
40739
|
const item = document.createElement("div");
|
|
40666
40740
|
item.className = "terminal-attachment";
|
|
40667
|
-
const
|
|
40668
|
-
|
|
40669
|
-
|
|
40741
|
+
const open2 = document.createElement("button");
|
|
40742
|
+
open2.type = "button";
|
|
40743
|
+
open2.className = "terminal-attachment-open";
|
|
40670
40744
|
const openLabel = deps.getText().openImage;
|
|
40671
|
-
|
|
40672
|
-
|
|
40673
|
-
|
|
40745
|
+
open2.title = path;
|
|
40746
|
+
open2.setAttribute("aria-label", `${openLabel}: ${name}`);
|
|
40747
|
+
open2.addEventListener("click", () => {
|
|
40674
40748
|
openImageLightbox({ url: src, name, path }, deps.getText());
|
|
40675
40749
|
});
|
|
40676
40750
|
const image2 = document.createElement("img");
|
|
@@ -40688,7 +40762,7 @@ ${formatErrorDetail(error2)}`
|
|
|
40688
40762
|
);
|
|
40689
40763
|
}
|
|
40690
40764
|
});
|
|
40691
|
-
|
|
40765
|
+
open2.appendChild(image2);
|
|
40692
40766
|
const label = document.createElement("span");
|
|
40693
40767
|
label.className = "terminal-attachment-name";
|
|
40694
40768
|
label.textContent = name;
|
|
@@ -40703,7 +40777,7 @@ ${formatErrorDetail(error2)}`
|
|
|
40703
40777
|
item.remove();
|
|
40704
40778
|
attachments.hidden = attachments.childElementCount === 0;
|
|
40705
40779
|
});
|
|
40706
|
-
item.append(
|
|
40780
|
+
item.append(open2, label, remove);
|
|
40707
40781
|
attachments.appendChild(item);
|
|
40708
40782
|
attachments.hidden = false;
|
|
40709
40783
|
}
|
|
@@ -40928,7 +41002,7 @@ ${formatErrorDetail(error2)}`
|
|
|
40928
41002
|
}
|
|
40929
41003
|
return null;
|
|
40930
41004
|
}
|
|
40931
|
-
|
|
41005
|
+
el2.addEventListener(
|
|
40932
41006
|
"paste",
|
|
40933
41007
|
(event) => {
|
|
40934
41008
|
const file = firstImage(event.clipboardData);
|
|
@@ -41080,7 +41154,7 @@ ${formatErrorDetail(error2)}`
|
|
|
41080
41154
|
deps.onStatus(null);
|
|
41081
41155
|
}
|
|
41082
41156
|
return {
|
|
41083
|
-
el,
|
|
41157
|
+
el: el2,
|
|
41084
41158
|
applyFontSize() {
|
|
41085
41159
|
if (!term) return;
|
|
41086
41160
|
term.options.fontSize = deps.getFontSize();
|
|
@@ -41562,7 +41636,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
41562
41636
|
const host = getMount();
|
|
41563
41637
|
return host ? !host.hidden : false;
|
|
41564
41638
|
}
|
|
41565
|
-
async function
|
|
41639
|
+
async function open2(id) {
|
|
41566
41640
|
const host = getMount();
|
|
41567
41641
|
if (!host || disposed) return;
|
|
41568
41642
|
const myGen = ++generation;
|
|
@@ -41621,7 +41695,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
41621
41695
|
renderLists();
|
|
41622
41696
|
}
|
|
41623
41697
|
return {
|
|
41624
|
-
open,
|
|
41698
|
+
open: open2,
|
|
41625
41699
|
close,
|
|
41626
41700
|
isOpen,
|
|
41627
41701
|
getActiveTarget: () => attached?.id ?? lastTargetId,
|
|
@@ -41772,8 +41846,8 @@ ${formatErrorDetail(error2)}`);
|
|
|
41772
41846
|
}
|
|
41773
41847
|
function createScratchpadPane(text3, outputTitle, placeholder, options) {
|
|
41774
41848
|
let currentText = text3;
|
|
41775
|
-
const
|
|
41776
|
-
|
|
41849
|
+
const el2 = document.createElement("div");
|
|
41850
|
+
el2.className = `tools-pane ${options.toolClassName}`;
|
|
41777
41851
|
const inputSide = document.createElement("section");
|
|
41778
41852
|
inputSide.className = "tools-pane-side tools-pane-input";
|
|
41779
41853
|
const { head: inputHead, titleEl: inputTitle } = createHead(text3.pane.input);
|
|
@@ -41808,7 +41882,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
41808
41882
|
const output = document.createElement("div");
|
|
41809
41883
|
output.className = "tools-pane-body";
|
|
41810
41884
|
outputSide.append(outputHead, output);
|
|
41811
|
-
|
|
41885
|
+
el2.append(inputSide, resizer, outputSide);
|
|
41812
41886
|
let statusTimer = null;
|
|
41813
41887
|
let pinnedStatus = null;
|
|
41814
41888
|
let normalStatus = { message: "", tone: "info" };
|
|
@@ -41888,21 +41962,21 @@ ${formatErrorDetail(error2)}`);
|
|
|
41888
41962
|
});
|
|
41889
41963
|
const MIN_SIDE_WIDTH = 220;
|
|
41890
41964
|
function applyInputWidth(width) {
|
|
41891
|
-
const total =
|
|
41965
|
+
const total = el2.getBoundingClientRect().width;
|
|
41892
41966
|
const max = Math.max(MIN_SIDE_WIDTH, total - MIN_SIDE_WIDTH);
|
|
41893
41967
|
const clamped = Math.max(MIN_SIDE_WIDTH, Math.min(max, width));
|
|
41894
|
-
|
|
41968
|
+
el2.style.setProperty("--tools-input-width", `${Math.round(clamped)}px`);
|
|
41895
41969
|
}
|
|
41896
41970
|
const detachResizer = attachDragResizer({
|
|
41897
41971
|
handle: resizer,
|
|
41898
41972
|
getSize: () => inputSide.getBoundingClientRect().width,
|
|
41899
41973
|
applySize: applyInputWidth,
|
|
41900
41974
|
direction: 1,
|
|
41901
|
-
activeClassTarget:
|
|
41975
|
+
activeClassTarget: el2,
|
|
41902
41976
|
activeClassName: "tools-pane-resizing"
|
|
41903
41977
|
});
|
|
41904
41978
|
return {
|
|
41905
|
-
el,
|
|
41979
|
+
el: el2,
|
|
41906
41980
|
input: input2,
|
|
41907
41981
|
output,
|
|
41908
41982
|
setStatus,
|
|
@@ -42426,7 +42500,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
42426
42500
|
const host = getMount();
|
|
42427
42501
|
return host ? !host.hidden : false;
|
|
42428
42502
|
}
|
|
42429
|
-
async function
|
|
42503
|
+
async function open2(tool) {
|
|
42430
42504
|
const host = getMount();
|
|
42431
42505
|
if (!host) return;
|
|
42432
42506
|
const myGen = ++generation;
|
|
@@ -42483,7 +42557,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
42483
42557
|
};
|
|
42484
42558
|
window.addEventListener("beforeunload", onBeforeUnload);
|
|
42485
42559
|
return {
|
|
42486
|
-
open,
|
|
42560
|
+
open: open2,
|
|
42487
42561
|
close,
|
|
42488
42562
|
isOpen,
|
|
42489
42563
|
getActiveTool: () => activeTool,
|
|
@@ -43137,6 +43211,1704 @@ ${formatErrorDetail(error2)}`);
|
|
|
43137
43211
|
return { mount, sync, localize };
|
|
43138
43212
|
}
|
|
43139
43213
|
|
|
43214
|
+
// web-src/views/worktree-i18n.ts
|
|
43215
|
+
var EN_STATUS_TITLES = {
|
|
43216
|
+
M: "modified",
|
|
43217
|
+
A: "added",
|
|
43218
|
+
D: "deleted",
|
|
43219
|
+
R: "renamed",
|
|
43220
|
+
C: "copied",
|
|
43221
|
+
U: "untracked"
|
|
43222
|
+
};
|
|
43223
|
+
var JA_STATUS_TITLES = {
|
|
43224
|
+
M: "変更",
|
|
43225
|
+
A: "追加",
|
|
43226
|
+
D: "削除",
|
|
43227
|
+
R: "リネーム",
|
|
43228
|
+
C: "コピー",
|
|
43229
|
+
U: "未追跡"
|
|
43230
|
+
};
|
|
43231
|
+
var TEXT3 = {
|
|
43232
|
+
en: {
|
|
43233
|
+
title: "Worktrees",
|
|
43234
|
+
ariaLabel: "Git worktrees",
|
|
43235
|
+
loading: "Loading worktrees…",
|
|
43236
|
+
loadFailed: "Failed to load worktrees.",
|
|
43237
|
+
empty: "No worktrees.",
|
|
43238
|
+
refresh: "Reload",
|
|
43239
|
+
refreshTitle: "Reload the worktree list",
|
|
43240
|
+
count: (n2) => n2 === 1 ? "1 worktree" : `${n2} worktrees`,
|
|
43241
|
+
baseUnknown: "no base branch found",
|
|
43242
|
+
gitignoreHint: "Git sees that directory as untracked. Add .worktrees/ to .gitignore to keep it out of git status.",
|
|
43243
|
+
badges: {
|
|
43244
|
+
current: "this folder",
|
|
43245
|
+
currentTitle: "This code-viewer is serving this folder",
|
|
43246
|
+
detached: "no branch",
|
|
43247
|
+
detachedTitle: "Not attached to any branch (detached HEAD)",
|
|
43248
|
+
bare: "bare",
|
|
43249
|
+
bareTitle: "A storage-only repository with no working files",
|
|
43250
|
+
locked: "locked",
|
|
43251
|
+
prunable: "stale entry",
|
|
43252
|
+
prunableTitle: "Only the git entry remains (e.g. the folder is gone)",
|
|
43253
|
+
missing: "folder is gone",
|
|
43254
|
+
running: "running",
|
|
43255
|
+
runningTitle: "A code-viewer for this folder is running on another port"
|
|
43256
|
+
},
|
|
43257
|
+
diverge: {
|
|
43258
|
+
ahead: (n2, base2) => n2 === 1 ? `1 commit ahead of ${base2}` : `${n2} commits ahead of ${base2}`,
|
|
43259
|
+
behind: (n2, base2) => n2 === 1 ? `1 commit behind ${base2}` : `${n2} commits behind ${base2}`,
|
|
43260
|
+
even: (base2) => `same point as ${base2}`,
|
|
43261
|
+
notComparable: "not compared"
|
|
43262
|
+
},
|
|
43263
|
+
merge: {
|
|
43264
|
+
clean: "merges cleanly",
|
|
43265
|
+
conflict: (n2) => n2 === 1 ? "1 file would conflict on merge" : `${n2} files would conflict on merge`,
|
|
43266
|
+
unknown: "could not check the merge",
|
|
43267
|
+
conflictListLabel: "Conflicting files"
|
|
43268
|
+
},
|
|
43269
|
+
files: {
|
|
43270
|
+
heading: (n2) => n2 === 1 ? "1 changed file" : `${n2} changed files`,
|
|
43271
|
+
none: "No changes.",
|
|
43272
|
+
uncommitted: "Not committed yet",
|
|
43273
|
+
committed: "Committed, not merged",
|
|
43274
|
+
truncated: (shown, total) => `showing ${shown} of ${total}`,
|
|
43275
|
+
// 行の中に置くので短くする。誰と重なっているかは title に入る。
|
|
43276
|
+
overlapMark: "shared",
|
|
43277
|
+
overlapTitle: (others) => `Also changed in: ${others.join(", ")}`,
|
|
43278
|
+
statusTitles: EN_STATUS_TITLES
|
|
43279
|
+
},
|
|
43280
|
+
overlaps: {
|
|
43281
|
+
heading: (n2) => n2 === 1 ? "1 file is touched by more than one worktree" : `${n2} files are touched by more than one worktree`,
|
|
43282
|
+
intro: "Merging one of them will make the others conflict on these files.",
|
|
43283
|
+
entry: (path, worktrees) => `${path} — ${worktrees.join(", ")}`
|
|
43284
|
+
},
|
|
43285
|
+
panes: {
|
|
43286
|
+
worktrees: "Worktrees",
|
|
43287
|
+
files: "Files",
|
|
43288
|
+
diff: "Diff",
|
|
43289
|
+
filterWorktrees: "Filter worktrees…",
|
|
43290
|
+
filterFiles: "Filter files…",
|
|
43291
|
+
noWorktreeMatch: "No worktree matches.",
|
|
43292
|
+
noFileMatch: "No file matches.",
|
|
43293
|
+
selectWorktree: "Pick a worktree to see what it is changing.",
|
|
43294
|
+
selectFile: "Pick a file to see its diff.",
|
|
43295
|
+
diffLoading: "Loading the diff…",
|
|
43296
|
+
diffEmpty: "No textual diff (binary, or the file is unchanged).",
|
|
43297
|
+
diffFailed: "Failed to load the diff.",
|
|
43298
|
+
diffTruncated: (shown, total) => `showing ${shown} of ${total} hunks — open the worktree in a new tab for the whole file`
|
|
43299
|
+
},
|
|
43300
|
+
noCommit: "no commit",
|
|
43301
|
+
lastTouched: (when) => `updated ${when}`,
|
|
43302
|
+
actions: {
|
|
43303
|
+
menuTitle: "Actions for this worktree",
|
|
43304
|
+
menuFor: (name) => `Actions for ${name}`,
|
|
43305
|
+
openFolder: "Open folder",
|
|
43306
|
+
openFolderTitle: "Open this folder in the OS file manager",
|
|
43307
|
+
openFolderFailed: "Could not open that folder.",
|
|
43308
|
+
copyPath: "Copy path",
|
|
43309
|
+
copyPathTitle: "Copy the path to this folder",
|
|
43310
|
+
copyFailed: "Could not copy to the clipboard.",
|
|
43311
|
+
stopServer: "Stop its server",
|
|
43312
|
+
stopServerTitle: "Stop the code-viewer running for this folder",
|
|
43313
|
+
stopFailed: "Failed to stop the server.",
|
|
43314
|
+
copyServerUrl: "Copy its address",
|
|
43315
|
+
copyServerUrlTitle: (url) => `Copy ${url}`,
|
|
43316
|
+
copyMerge: "Copy merge command",
|
|
43317
|
+
copyMergeTitle: (base2, branch) => `Copy the command that merges ${branch} into ${base2}`
|
|
43318
|
+
},
|
|
43319
|
+
emptyDiff: {
|
|
43320
|
+
title: "No changes yet.",
|
|
43321
|
+
body: (path) => `Edit files in ${path} and the diffs will show up here.`
|
|
43322
|
+
},
|
|
43323
|
+
intro: {
|
|
43324
|
+
cardTitle: "What is a worktree?",
|
|
43325
|
+
cardWhat: "A worktree (git worktree) is a second checkout of this repository, in a separate folder on a separate branch.",
|
|
43326
|
+
cardWhy: "Keep main open here while a bugfix branch stays open over there — no branch switching, no stashing.",
|
|
43327
|
+
cardHow: 'When you click "Create": a new folder appears at .worktrees/<name>, with the branch checked out in it. Edit files there as usual. The changes show up on this screen as diffs.',
|
|
43328
|
+
cardButton: "Create a worktree",
|
|
43329
|
+
listNote: "This is the only folder right now. New worktrees will appear here.",
|
|
43330
|
+
overlapLegend: "⇄ = another worktree is changing this file too"
|
|
43331
|
+
},
|
|
43332
|
+
open: "Open in a new tab",
|
|
43333
|
+
openTitle: "Start a code-viewer for this folder and open it in a new tab",
|
|
43334
|
+
opening: "Starting…",
|
|
43335
|
+
openFailed: "Failed to open this worktree.",
|
|
43336
|
+
add: "Create",
|
|
43337
|
+
addTitle: "Create a new worktree",
|
|
43338
|
+
addFailed: "Failed to create the worktree.",
|
|
43339
|
+
addDialog: {
|
|
43340
|
+
title: "Create a worktree",
|
|
43341
|
+
intro: "Work on two things side by side, in separate folders, without switching branches.",
|
|
43342
|
+
nameLabel: "Folder name",
|
|
43343
|
+
namePlaceholder: "feature-x",
|
|
43344
|
+
branchLabel: "Branch",
|
|
43345
|
+
branchPlaceholder: "same as the folder name",
|
|
43346
|
+
branchHint: "An existing branch name opens that branch. Otherwise a new one starts from where you are now.",
|
|
43347
|
+
targetLabel: "Creates",
|
|
43348
|
+
targetPending: (parent) => `${parent}/…`,
|
|
43349
|
+
gitignoreLabel: "About this folder and git status",
|
|
43350
|
+
submit: "Create"
|
|
43351
|
+
},
|
|
43352
|
+
remove: "Delete this worktree",
|
|
43353
|
+
removeTitle: "Delete this worktree and its folder",
|
|
43354
|
+
removeDialog: {
|
|
43355
|
+
title: "Delete worktree",
|
|
43356
|
+
body: (name) => `Delete the worktree "${name}"?`,
|
|
43357
|
+
diskNote: (path) => `The folder ${path} and everything in it will be deleted from disk. This cannot be undone.`,
|
|
43358
|
+
branchNote: (branch) => `The branch ${branch} and its committed work are kept.`,
|
|
43359
|
+
dirtyNote: (count) => count === 1 ? "1 file has uncommitted changes." : `${count} files have uncommitted changes.`,
|
|
43360
|
+
dirtyLose: "Deleting the worktree will lose them.",
|
|
43361
|
+
force: "Delete even with uncommitted changes",
|
|
43362
|
+
forceRequired: "To delete it anyway, check the box first.",
|
|
43363
|
+
missingBody: (name) => `Remove the entry for "${name}"?`,
|
|
43364
|
+
missingNote: "Its folder is already gone from disk; only the git entry is removed.",
|
|
43365
|
+
lockedNote: "This entry is locked, so git will leave it in place. Unlock it first.",
|
|
43366
|
+
missingOthers: (n2) => n2 === 1 ? "1 other entry whose folder is gone will be cleaned up at the same time." : `${n2} other entries whose folders are gone will be cleaned up at the same time.`,
|
|
43367
|
+
submit: "Delete"
|
|
43368
|
+
},
|
|
43369
|
+
removeFailed: "Failed to delete the worktree.",
|
|
43370
|
+
cancel: "Cancel",
|
|
43371
|
+
nameErrors: {
|
|
43372
|
+
empty: "Enter a name.",
|
|
43373
|
+
control: "Control characters cannot be used.",
|
|
43374
|
+
separator: "Path separators cannot be used.",
|
|
43375
|
+
relative: "This name is not allowed.",
|
|
43376
|
+
"leading-dot": "The name cannot start with a dot.",
|
|
43377
|
+
"too-long": "The name is too long."
|
|
43378
|
+
}
|
|
43379
|
+
},
|
|
43380
|
+
ja: {
|
|
43381
|
+
title: "作業ツリー",
|
|
43382
|
+
ariaLabel: "git の作業ツリー",
|
|
43383
|
+
loading: "作業ツリーを読み込んでいます…",
|
|
43384
|
+
loadFailed: "作業ツリーを読み込めませんでした。",
|
|
43385
|
+
empty: "作業ツリーがありません。",
|
|
43386
|
+
refresh: "再読み込み",
|
|
43387
|
+
refreshTitle: "一覧を読み直す",
|
|
43388
|
+
count: (n2) => `${n2} 本`,
|
|
43389
|
+
baseUnknown: "比較の基準になるブランチが見つかりません",
|
|
43390
|
+
gitignoreHint: "このディレクトリは git から未追跡に見えます。.worktrees/ を .gitignore に入れると git status に出なくなります。",
|
|
43391
|
+
badges: {
|
|
43392
|
+
current: "このフォルダ",
|
|
43393
|
+
currentTitle: "この code-viewer が開いているフォルダです",
|
|
43394
|
+
detached: "ブランチなし",
|
|
43395
|
+
detachedTitle: "どのブランチにも紐づいていません(detached HEAD)",
|
|
43396
|
+
bare: "bare",
|
|
43397
|
+
bareTitle: "作業ファイルを持たない保管用のリポジトリです",
|
|
43398
|
+
locked: "ロック中",
|
|
43399
|
+
prunable: "掃除できます",
|
|
43400
|
+
prunableTitle: "フォルダが無い等で管理情報だけ残っています",
|
|
43401
|
+
missing: "フォルダがありません",
|
|
43402
|
+
running: "起動中",
|
|
43403
|
+
runningTitle: "このフォルダ専用の code-viewer が別ポートで動いています"
|
|
43404
|
+
},
|
|
43405
|
+
diverge: {
|
|
43406
|
+
ahead: (n2, base2) => `${base2} より ${n2} コミット進んでいます`,
|
|
43407
|
+
behind: (n2, base2) => `${base2} より ${n2} コミット遅れています`,
|
|
43408
|
+
even: (base2) => `${base2} と同じ地点です`,
|
|
43409
|
+
notComparable: "比較なし"
|
|
43410
|
+
},
|
|
43411
|
+
merge: {
|
|
43412
|
+
clean: "そのままマージできます",
|
|
43413
|
+
conflict: (n2) => `マージすると ${n2} ファイルで衝突します`,
|
|
43414
|
+
unknown: "マージできるか確かめられませんでした",
|
|
43415
|
+
conflictListLabel: "衝突するファイル"
|
|
43416
|
+
},
|
|
43417
|
+
files: {
|
|
43418
|
+
heading: (n2) => `変更 ${n2} 件`,
|
|
43419
|
+
none: "変更はありません。",
|
|
43420
|
+
uncommitted: "未コミット",
|
|
43421
|
+
committed: "コミット済み・未マージ",
|
|
43422
|
+
truncated: (shown, total) => `${total} 件のうち ${shown} 件を表示`,
|
|
43423
|
+
// 行の中に置くので短くする。誰と重なっているかは title に入る。
|
|
43424
|
+
overlapMark: "重複",
|
|
43425
|
+
overlapTitle: (others) => `同じファイルを触っている: ${others.join("、")}`,
|
|
43426
|
+
statusTitles: JA_STATUS_TITLES
|
|
43427
|
+
},
|
|
43428
|
+
overlaps: {
|
|
43429
|
+
heading: (n2) => `${n2} 個のファイルを 2 本以上が触っています`,
|
|
43430
|
+
intro: "どれか 1 本をマージすると、残りはこのファイルで衝突します。",
|
|
43431
|
+
entry: (path, worktrees) => `${path} — ${worktrees.join("、")}`
|
|
43432
|
+
},
|
|
43433
|
+
panes: {
|
|
43434
|
+
worktrees: "作業ツリー",
|
|
43435
|
+
files: "ファイル",
|
|
43436
|
+
diff: "差分",
|
|
43437
|
+
filterWorktrees: "作業ツリーを絞り込み…",
|
|
43438
|
+
filterFiles: "ファイルを絞り込み…",
|
|
43439
|
+
noWorktreeMatch: "該当する作業ツリーがありません。",
|
|
43440
|
+
noFileMatch: "該当するファイルがありません。",
|
|
43441
|
+
selectWorktree: "作業ツリーを選ぶと、何を触っているかが出ます。",
|
|
43442
|
+
selectFile: "ファイルを選ぶと差分が出ます。",
|
|
43443
|
+
diffLoading: "差分を読み込んでいます…",
|
|
43444
|
+
diffEmpty: "テキストの差分はありません(バイナリか、変更なし)。",
|
|
43445
|
+
diffFailed: "差分を読み込めませんでした。",
|
|
43446
|
+
diffTruncated: (shown, total) => `${total} 個のうち ${shown} 個のかたまりを表示しています。全部見るには、その作業ツリーを別タブで見てください`
|
|
43447
|
+
},
|
|
43448
|
+
noCommit: "コミットなし",
|
|
43449
|
+
lastTouched: (when) => `最終更新 ${when}`,
|
|
43450
|
+
actions: {
|
|
43451
|
+
menuTitle: "この作業ツリーへの操作",
|
|
43452
|
+
menuFor: (name) => `${name} への操作`,
|
|
43453
|
+
openFolder: "フォルダを開く",
|
|
43454
|
+
openFolderTitle: "このフォルダをファイルマネージャで開きます",
|
|
43455
|
+
openFolderFailed: "そのフォルダを開けませんでした。",
|
|
43456
|
+
copyPath: "パスをコピー",
|
|
43457
|
+
copyPathTitle: "このフォルダの場所をコピーします",
|
|
43458
|
+
copyFailed: "クリップボードにコピーできませんでした。",
|
|
43459
|
+
stopServer: "サーバを止める",
|
|
43460
|
+
stopServerTitle: "このフォルダで動いている code-viewer を止めます",
|
|
43461
|
+
stopFailed: "サーバを止められませんでした。",
|
|
43462
|
+
copyServerUrl: "アドレスをコピー",
|
|
43463
|
+
copyServerUrlTitle: (url) => `${url} をコピーします`,
|
|
43464
|
+
copyMerge: "マージのコマンドをコピー",
|
|
43465
|
+
copyMergeTitle: (base2, branch) => `${branch} を ${base2} に取り込むコマンドをコピーします`
|
|
43466
|
+
},
|
|
43467
|
+
emptyDiff: {
|
|
43468
|
+
title: "まだ変更はありません。",
|
|
43469
|
+
body: (path) => `${path} でファイルを編集すると、ここに差分が出ます。`
|
|
43470
|
+
},
|
|
43471
|
+
intro: {
|
|
43472
|
+
cardTitle: "作業ツリー(git worktree)とは",
|
|
43473
|
+
cardWhat: "同じリポジトリを、ブランチを切り替えずに別フォルダでもう 1 つ開く仕組みです。",
|
|
43474
|
+
cardWhy: "main で作業しながら、別フォルダで修正用のブランチを開いておけます。2 つの作業を並べて進められます。",
|
|
43475
|
+
cardHow: "「作る」を押すと .worktrees/〈名前〉 にフォルダができ、指定したブランチがそこに展開されます。あとはそのフォルダで普通に編集してください。変更はこの画面に差分として出ます。",
|
|
43476
|
+
cardButton: "作業ツリーを作る",
|
|
43477
|
+
listNote: "いまはこのフォルダだけです。作業ツリーを作ると、ここに並びます。",
|
|
43478
|
+
overlapLegend: "⇄ = 他の作業ツリーも同じファイルを触っている"
|
|
43479
|
+
},
|
|
43480
|
+
open: "別タブで見る",
|
|
43481
|
+
openTitle: "このフォルダ専用の code-viewer を起動して新しいタブで開きます",
|
|
43482
|
+
opening: "起動中…",
|
|
43483
|
+
openFailed: "この作業ツリーを開けませんでした。",
|
|
43484
|
+
add: "作る",
|
|
43485
|
+
addTitle: "作業ツリーを新しく作る",
|
|
43486
|
+
addFailed: "作業ツリーを作れませんでした。",
|
|
43487
|
+
addDialog: {
|
|
43488
|
+
title: "作業ツリーを作る",
|
|
43489
|
+
intro: "ブランチを切り替えずに、別フォルダで 2 つの作業を並べて進められます。",
|
|
43490
|
+
nameLabel: "フォルダ名",
|
|
43491
|
+
namePlaceholder: "feature-x",
|
|
43492
|
+
branchLabel: "ブランチ",
|
|
43493
|
+
branchPlaceholder: "フォルダ名と同じ",
|
|
43494
|
+
branchHint: "既にあるブランチ名ならそれを開きます。無ければ、いまの地点から新しく作ります。",
|
|
43495
|
+
targetLabel: "作成先",
|
|
43496
|
+
targetPending: (parent) => `${parent}/…`,
|
|
43497
|
+
gitignoreLabel: "このフォルダと git status について",
|
|
43498
|
+
submit: "作る"
|
|
43499
|
+
},
|
|
43500
|
+
remove: "この作業ツリーを削除",
|
|
43501
|
+
removeTitle: "この作業ツリーをフォルダごと削除します",
|
|
43502
|
+
removeDialog: {
|
|
43503
|
+
title: "作業ツリーの削除",
|
|
43504
|
+
body: (name) => `作業ツリー「${name}」を削除しますか。`,
|
|
43505
|
+
diskNote: (path) => `フォルダ ${path} とその中身はディスクから消えます。元に戻せません。`,
|
|
43506
|
+
branchNote: (branch) => `ブランチ ${branch} と、コミット済みの内容は残ります。`,
|
|
43507
|
+
dirtyNote: (count) => `コミットしていない変更が ${count} 件あります。`,
|
|
43508
|
+
dirtyLose: "削除するとこれらの変更は失われます。",
|
|
43509
|
+
force: "変更が残っていても削除する",
|
|
43510
|
+
forceRequired: "変更を捨てて削除するには、チェックを入れてください。",
|
|
43511
|
+
missingBody: (name) => `作業ツリー「${name}」の登録を消しますか。`,
|
|
43512
|
+
missingNote: "フォルダは既にディスク上にありません。git の管理情報だけを消します。",
|
|
43513
|
+
lockedNote: "この登録はロックされているので、git はそのまま残します。先にロックを外してください。",
|
|
43514
|
+
missingOthers: (n2) => `フォルダが無くなっている他の登録 ${n2} 件も、同時に整理されます。`,
|
|
43515
|
+
submit: "削除する"
|
|
43516
|
+
},
|
|
43517
|
+
removeFailed: "作業ツリーを削除できませんでした。",
|
|
43518
|
+
cancel: "キャンセル",
|
|
43519
|
+
nameErrors: {
|
|
43520
|
+
empty: "名前を入力してください。",
|
|
43521
|
+
control: "制御文字は使えません。",
|
|
43522
|
+
separator: "パス区切りは使えません。",
|
|
43523
|
+
relative: "この名前は使えません。",
|
|
43524
|
+
"leading-dot": "ドットで始まる名前は使えません。",
|
|
43525
|
+
"too-long": "名前が長すぎます。"
|
|
43526
|
+
}
|
|
43527
|
+
}
|
|
43528
|
+
};
|
|
43529
|
+
function worktreeText(lang) {
|
|
43530
|
+
return TEXT3[lang];
|
|
43531
|
+
}
|
|
43532
|
+
|
|
43533
|
+
// web-src/core/worktree.ts
|
|
43534
|
+
var WORKTREE_NAME_MAX_LENGTH = 100;
|
|
43535
|
+
function worktreeNameError(name) {
|
|
43536
|
+
if (!name) return "empty";
|
|
43537
|
+
if (name.length > WORKTREE_NAME_MAX_LENGTH) return "too-long";
|
|
43538
|
+
for (const ch of name) {
|
|
43539
|
+
const code2 = ch.charCodeAt(0);
|
|
43540
|
+
if (code2 < 32 || code2 === 127) return "control";
|
|
43541
|
+
}
|
|
43542
|
+
if (name.includes("/") || name.includes("\\")) return "separator";
|
|
43543
|
+
if (name === "." || name === "..") return "relative";
|
|
43544
|
+
if (name.startsWith(".")) return "leading-dot";
|
|
43545
|
+
return null;
|
|
43546
|
+
}
|
|
43547
|
+
function worktreeBranchError(branch) {
|
|
43548
|
+
if (!branch) return "empty";
|
|
43549
|
+
if (branch.length > WORKTREE_NAME_MAX_LENGTH) return "too-long";
|
|
43550
|
+
for (const ch of branch) {
|
|
43551
|
+
const code2 = ch.charCodeAt(0);
|
|
43552
|
+
if (code2 < 32 || code2 === 127) return "control";
|
|
43553
|
+
}
|
|
43554
|
+
if (branch.startsWith("-") || branch.includes("..")) return "relative";
|
|
43555
|
+
return null;
|
|
43556
|
+
}
|
|
43557
|
+
|
|
43558
|
+
// web-src/views/context-menu.ts
|
|
43559
|
+
var open = null;
|
|
43560
|
+
function closeContextMenu() {
|
|
43561
|
+
if (!open) return;
|
|
43562
|
+
const closing = open;
|
|
43563
|
+
open = null;
|
|
43564
|
+
closing.cleanup();
|
|
43565
|
+
closing.element.remove();
|
|
43566
|
+
}
|
|
43567
|
+
function showContextMenu(anchor, items) {
|
|
43568
|
+
closeContextMenu();
|
|
43569
|
+
const menu = document.createElement("div");
|
|
43570
|
+
menu.className = "gdp-context-menu";
|
|
43571
|
+
menu.setAttribute("role", "menu");
|
|
43572
|
+
for (const item of items) {
|
|
43573
|
+
if (item.kind === "separator") {
|
|
43574
|
+
const line = document.createElement("hr");
|
|
43575
|
+
line.className = "gdp-context-menu-sep";
|
|
43576
|
+
menu.appendChild(line);
|
|
43577
|
+
continue;
|
|
43578
|
+
}
|
|
43579
|
+
const button = document.createElement("button");
|
|
43580
|
+
button.type = "button";
|
|
43581
|
+
button.setAttribute("role", "menuitem");
|
|
43582
|
+
button.textContent = item.label;
|
|
43583
|
+
if (item.title) button.title = item.title;
|
|
43584
|
+
if (item.danger) button.classList.add("danger");
|
|
43585
|
+
button.disabled = !!item.disabled;
|
|
43586
|
+
button.addEventListener("click", () => {
|
|
43587
|
+
closeContextMenu();
|
|
43588
|
+
item.onSelect();
|
|
43589
|
+
});
|
|
43590
|
+
menu.appendChild(button);
|
|
43591
|
+
}
|
|
43592
|
+
document.body.appendChild(menu);
|
|
43593
|
+
const rect = menu.getBoundingClientRect();
|
|
43594
|
+
const from = anchor.getBoundingClientRect();
|
|
43595
|
+
const left = Math.min(
|
|
43596
|
+
from.right - rect.width,
|
|
43597
|
+
window.innerWidth - rect.width - 8
|
|
43598
|
+
);
|
|
43599
|
+
const top = Math.min(from.bottom + 4, window.innerHeight - rect.height - 8);
|
|
43600
|
+
menu.style.left = `${Math.max(8, left)}px`;
|
|
43601
|
+
menu.style.top = `${Math.max(8, top)}px`;
|
|
43602
|
+
const onPointerDown = (event) => {
|
|
43603
|
+
if (menu.contains(event.target)) return;
|
|
43604
|
+
closeContextMenu();
|
|
43605
|
+
};
|
|
43606
|
+
const onKeyDown = (event) => {
|
|
43607
|
+
if (event.key !== "Escape") return;
|
|
43608
|
+
event.stopPropagation();
|
|
43609
|
+
closeContextMenu();
|
|
43610
|
+
anchor.focus();
|
|
43611
|
+
};
|
|
43612
|
+
const onScroll = () => closeContextMenu();
|
|
43613
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
43614
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
43615
|
+
window.addEventListener("scroll", onScroll, true);
|
|
43616
|
+
window.addEventListener("resize", onScroll);
|
|
43617
|
+
open = {
|
|
43618
|
+
element: menu,
|
|
43619
|
+
cleanup() {
|
|
43620
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
43621
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
43622
|
+
window.removeEventListener("scroll", onScroll, true);
|
|
43623
|
+
window.removeEventListener("resize", onScroll);
|
|
43624
|
+
}
|
|
43625
|
+
};
|
|
43626
|
+
menu.querySelector("button:not(:disabled)")?.focus();
|
|
43627
|
+
}
|
|
43628
|
+
|
|
43629
|
+
// web-src/views/worktree-view.ts
|
|
43630
|
+
var SSE_REFRESH_DELAY_MS = 400;
|
|
43631
|
+
var DIFF_PREFETCH_MARGIN = "600px";
|
|
43632
|
+
var ACTION_HEADERS = {
|
|
43633
|
+
"Content-Type": "application/json",
|
|
43634
|
+
"X-Code-Viewer-Action": "1"
|
|
43635
|
+
};
|
|
43636
|
+
async function postWorktreeAction(path, body) {
|
|
43637
|
+
const res = await fetch(path, {
|
|
43638
|
+
method: "POST",
|
|
43639
|
+
headers: ACTION_HEADERS,
|
|
43640
|
+
body: JSON.stringify(body)
|
|
43641
|
+
});
|
|
43642
|
+
if (!res.ok) throw new Error(await res.text() || `${res.status}`);
|
|
43643
|
+
return await res.json();
|
|
43644
|
+
}
|
|
43645
|
+
function el(tag, className, text3) {
|
|
43646
|
+
const node = document.createElement(tag);
|
|
43647
|
+
if (className) node.className = className;
|
|
43648
|
+
if (text3 !== void 0) node.textContent = text3;
|
|
43649
|
+
return node;
|
|
43650
|
+
}
|
|
43651
|
+
function fileKey(file) {
|
|
43652
|
+
return `${file.origin}:${file.path}`;
|
|
43653
|
+
}
|
|
43654
|
+
function chevronSvg() {
|
|
43655
|
+
return iconSvg("octicon-chevron-down", CHEVRON_DOWN_16_PATH);
|
|
43656
|
+
}
|
|
43657
|
+
function folderSvg(collapsed) {
|
|
43658
|
+
return iconSvg(
|
|
43659
|
+
collapsed ? "octicon-file-directory-fill" : "octicon-file-directory-open-fill",
|
|
43660
|
+
collapsed ? FOLDER_ICON_PATHS.closed : FOLDER_ICON_PATHS.open
|
|
43661
|
+
);
|
|
43662
|
+
}
|
|
43663
|
+
function matches(haystack, needle) {
|
|
43664
|
+
return !needle || haystack.toLowerCase().includes(needle.toLowerCase());
|
|
43665
|
+
}
|
|
43666
|
+
function createWorktreeView(deps) {
|
|
43667
|
+
let mounted = false;
|
|
43668
|
+
let lifecycle = 0;
|
|
43669
|
+
let acceptedServerGeneration = 0;
|
|
43670
|
+
let data = null;
|
|
43671
|
+
let message = "";
|
|
43672
|
+
let messageIsError = false;
|
|
43673
|
+
let busyPath = "";
|
|
43674
|
+
let sseTimer = null;
|
|
43675
|
+
let refreshRequested = false;
|
|
43676
|
+
let refreshLoop = null;
|
|
43677
|
+
let worktreeFilter = "";
|
|
43678
|
+
let fileFilter = "";
|
|
43679
|
+
let diffFor = null;
|
|
43680
|
+
let restoredRouteKey = null;
|
|
43681
|
+
let observer = null;
|
|
43682
|
+
const listPanel = document.getElementById("worktree-panel");
|
|
43683
|
+
function text3() {
|
|
43684
|
+
return deps.getText();
|
|
43685
|
+
}
|
|
43686
|
+
function route() {
|
|
43687
|
+
const current = deps.getRoute();
|
|
43688
|
+
return current.screen === "worktree" ? current : null;
|
|
43689
|
+
}
|
|
43690
|
+
function setMessage(next, isError = false) {
|
|
43691
|
+
message = next;
|
|
43692
|
+
messageIsError = isError;
|
|
43693
|
+
}
|
|
43694
|
+
function isCurrent(seq) {
|
|
43695
|
+
return mounted && seq === lifecycle && route() !== null;
|
|
43696
|
+
}
|
|
43697
|
+
const worktreeFilterInput = (() => {
|
|
43698
|
+
const input2 = el("input", "history-filter");
|
|
43699
|
+
input2.type = "search";
|
|
43700
|
+
input2.autocomplete = "off";
|
|
43701
|
+
input2.addEventListener("input", () => {
|
|
43702
|
+
worktreeFilter = input2.value;
|
|
43703
|
+
renderList();
|
|
43704
|
+
});
|
|
43705
|
+
return input2;
|
|
43706
|
+
})();
|
|
43707
|
+
function sidebarFilter() {
|
|
43708
|
+
return document.querySelector("#sb-filter");
|
|
43709
|
+
}
|
|
43710
|
+
function onSidebarFilter() {
|
|
43711
|
+
fileFilter = sidebarFilter()?.value || "";
|
|
43712
|
+
renderFiles();
|
|
43713
|
+
}
|
|
43714
|
+
function onSidebarViewToggle() {
|
|
43715
|
+
window.setTimeout(() => renderFiles(), 0);
|
|
43716
|
+
}
|
|
43717
|
+
function setAllDirsCollapsed(collapsed) {
|
|
43718
|
+
const list2 = document.getElementById("filelist");
|
|
43719
|
+
if (!list2) return;
|
|
43720
|
+
for (const dir of list2.querySelectorAll(".tree-dir")) {
|
|
43721
|
+
dir.classList.toggle("collapsed", collapsed);
|
|
43722
|
+
const icon = dir.querySelector(":scope > .dir-icon");
|
|
43723
|
+
if (icon) icon.innerHTML = folderSvg(collapsed);
|
|
43724
|
+
}
|
|
43725
|
+
}
|
|
43726
|
+
function onExpandAll() {
|
|
43727
|
+
setAllDirsCollapsed(false);
|
|
43728
|
+
}
|
|
43729
|
+
function onCollapseAll() {
|
|
43730
|
+
setAllDirsCollapsed(true);
|
|
43731
|
+
}
|
|
43732
|
+
function sidebarViewButtons() {
|
|
43733
|
+
return Array.from(
|
|
43734
|
+
document.querySelectorAll(".sb-view-seg button")
|
|
43735
|
+
);
|
|
43736
|
+
}
|
|
43737
|
+
function mount() {
|
|
43738
|
+
if (mounted || !listPanel) return;
|
|
43739
|
+
document.getElementById("empty")?.classList.add("hidden");
|
|
43740
|
+
document.getElementById("history-commit-info")?.setAttribute("hidden", "true");
|
|
43741
|
+
listPanel.hidden = false;
|
|
43742
|
+
mounted = true;
|
|
43743
|
+
document.body.classList.add("gdp-worktree-page");
|
|
43744
|
+
sidebarFilter()?.addEventListener("input", onSidebarFilter);
|
|
43745
|
+
document.getElementById("filelist")?.addEventListener("click", onFileListClick);
|
|
43746
|
+
for (const button of sidebarViewButtons()) {
|
|
43747
|
+
button.addEventListener("click", onSidebarViewToggle);
|
|
43748
|
+
}
|
|
43749
|
+
document.getElementById("sb-expand-all")?.addEventListener("click", onExpandAll);
|
|
43750
|
+
document.getElementById("sb-collapse-all")?.addEventListener("click", onCollapseAll);
|
|
43751
|
+
deps.setPageMode();
|
|
43752
|
+
deps.syncHeaderMenu();
|
|
43753
|
+
}
|
|
43754
|
+
function suspend() {
|
|
43755
|
+
lifecycle++;
|
|
43756
|
+
closeContextMenu();
|
|
43757
|
+
observer?.disconnect();
|
|
43758
|
+
observer = null;
|
|
43759
|
+
diffFor = null;
|
|
43760
|
+
restoredRouteKey = null;
|
|
43761
|
+
if (sseTimer !== null) {
|
|
43762
|
+
window.clearTimeout(sseTimer);
|
|
43763
|
+
sseTimer = null;
|
|
43764
|
+
}
|
|
43765
|
+
refreshRequested = false;
|
|
43766
|
+
if (listPanel) {
|
|
43767
|
+
listPanel.hidden = true;
|
|
43768
|
+
listPanel.replaceChildren();
|
|
43769
|
+
}
|
|
43770
|
+
sidebarFilter()?.removeEventListener("input", onSidebarFilter);
|
|
43771
|
+
document.getElementById("filelist")?.removeEventListener("click", onFileListClick);
|
|
43772
|
+
for (const button of sidebarViewButtons()) {
|
|
43773
|
+
button.removeEventListener("click", onSidebarViewToggle);
|
|
43774
|
+
}
|
|
43775
|
+
document.getElementById("sb-expand-all")?.removeEventListener("click", onExpandAll);
|
|
43776
|
+
document.getElementById("sb-collapse-all")?.removeEventListener("click", onCollapseAll);
|
|
43777
|
+
document.getElementById("filelist")?.replaceChildren();
|
|
43778
|
+
document.getElementById("diff")?.replaceChildren();
|
|
43779
|
+
document.body.classList.remove("gdp-worktree-page");
|
|
43780
|
+
mounted = false;
|
|
43781
|
+
}
|
|
43782
|
+
function selectedWorktree() {
|
|
43783
|
+
const id = route()?.wt;
|
|
43784
|
+
if (!id || !data) return null;
|
|
43785
|
+
return data.worktrees.find((item) => item.id === id) || null;
|
|
43786
|
+
}
|
|
43787
|
+
function worktreeLabel(id) {
|
|
43788
|
+
const item = data?.worktrees.find((candidate) => candidate.id === id);
|
|
43789
|
+
if (!item) return id;
|
|
43790
|
+
const sameName = data?.worktrees.filter(
|
|
43791
|
+
(candidate) => candidate.name === item.name
|
|
43792
|
+
);
|
|
43793
|
+
return sameName && sameName.length > 1 ? `${item.name} (${item.displayPath})` : item.name;
|
|
43794
|
+
}
|
|
43795
|
+
function navigate(next, replace2 = false) {
|
|
43796
|
+
const current = route();
|
|
43797
|
+
if (!current) return;
|
|
43798
|
+
deps.setRoute(
|
|
43799
|
+
{
|
|
43800
|
+
screen: "worktree",
|
|
43801
|
+
...current.wt ? { wt: current.wt } : {},
|
|
43802
|
+
...current.file ? { file: current.file } : {},
|
|
43803
|
+
...current.origin ? { origin: current.origin } : {},
|
|
43804
|
+
...next,
|
|
43805
|
+
range: deps.currentRange()
|
|
43806
|
+
},
|
|
43807
|
+
replace2
|
|
43808
|
+
);
|
|
43809
|
+
}
|
|
43810
|
+
async function refreshOnce() {
|
|
43811
|
+
if (!mounted || !route()) return;
|
|
43812
|
+
const seq = ++lifecycle;
|
|
43813
|
+
if (!data) setMessage(text3().loading);
|
|
43814
|
+
renderList();
|
|
43815
|
+
deps.setStatus("refreshing");
|
|
43816
|
+
try {
|
|
43817
|
+
const next = await deps.trackLoad(
|
|
43818
|
+
fetch("/_worktree/list").then(async (res) => {
|
|
43819
|
+
if (!res.ok) throw new Error(await res.text() || `${res.status}`);
|
|
43820
|
+
return await res.json();
|
|
43821
|
+
})
|
|
43822
|
+
);
|
|
43823
|
+
if (!isCurrent(seq)) return;
|
|
43824
|
+
if (!Number.isInteger(next.generation) || next.generation < acceptedServerGeneration) {
|
|
43825
|
+
throw new Error(
|
|
43826
|
+
`stale worktree response generation ${next.generation}; current is ${acceptedServerGeneration}`
|
|
43827
|
+
);
|
|
43828
|
+
}
|
|
43829
|
+
acceptedServerGeneration = next.generation;
|
|
43830
|
+
data = next;
|
|
43831
|
+
setMessage(next.error || "", !!next.error);
|
|
43832
|
+
deps.setStatus(next.error ? "error" : "live");
|
|
43833
|
+
} catch (error2) {
|
|
43834
|
+
if (!isCurrent(seq)) return;
|
|
43835
|
+
setMessage(
|
|
43836
|
+
error2 instanceof Error ? error2.message : text3().loadFailed,
|
|
43837
|
+
true
|
|
43838
|
+
);
|
|
43839
|
+
deps.setStatus("error");
|
|
43840
|
+
} finally {
|
|
43841
|
+
if (isCurrent(seq)) {
|
|
43842
|
+
diffFor = null;
|
|
43843
|
+
render();
|
|
43844
|
+
}
|
|
43845
|
+
}
|
|
43846
|
+
}
|
|
43847
|
+
function refresh() {
|
|
43848
|
+
if (!mounted || !route()) return Promise.resolve();
|
|
43849
|
+
refreshRequested = true;
|
|
43850
|
+
if (refreshLoop) return refreshLoop;
|
|
43851
|
+
const loop = (async () => {
|
|
43852
|
+
while (refreshRequested && mounted && route()) {
|
|
43853
|
+
refreshRequested = false;
|
|
43854
|
+
await refreshOnce();
|
|
43855
|
+
}
|
|
43856
|
+
})();
|
|
43857
|
+
const tracked = loop.finally(() => {
|
|
43858
|
+
if (refreshLoop === tracked) refreshLoop = null;
|
|
43859
|
+
});
|
|
43860
|
+
refreshLoop = tracked;
|
|
43861
|
+
return tracked;
|
|
43862
|
+
}
|
|
43863
|
+
function openBlankTab() {
|
|
43864
|
+
try {
|
|
43865
|
+
const tab = window.open("", "_blank");
|
|
43866
|
+
if (tab) tab.opener = null;
|
|
43867
|
+
return tab;
|
|
43868
|
+
} catch {
|
|
43869
|
+
return null;
|
|
43870
|
+
}
|
|
43871
|
+
}
|
|
43872
|
+
async function openWorktree(item) {
|
|
43873
|
+
if (busyPath) return;
|
|
43874
|
+
const seq = lifecycle;
|
|
43875
|
+
busyPath = item.path;
|
|
43876
|
+
setMessage(text3().opening);
|
|
43877
|
+
renderList();
|
|
43878
|
+
const tab = openBlankTab();
|
|
43879
|
+
try {
|
|
43880
|
+
const result = await deps.trackLoad(
|
|
43881
|
+
postWorktreeAction("/_worktree/open", { path: item.path })
|
|
43882
|
+
);
|
|
43883
|
+
const url = result.url || "";
|
|
43884
|
+
if (!url) throw new Error(text3().openFailed);
|
|
43885
|
+
if (tab) tab.location.href = url;
|
|
43886
|
+
if (isCurrent(seq)) setMessage(tab ? "" : url, !tab);
|
|
43887
|
+
} catch (error2) {
|
|
43888
|
+
tab?.close();
|
|
43889
|
+
if (isCurrent(seq)) {
|
|
43890
|
+
setMessage(
|
|
43891
|
+
error2 instanceof Error ? error2.message : text3().openFailed,
|
|
43892
|
+
true
|
|
43893
|
+
);
|
|
43894
|
+
}
|
|
43895
|
+
} finally {
|
|
43896
|
+
busyPath = "";
|
|
43897
|
+
if (isCurrent(seq)) await refresh();
|
|
43898
|
+
}
|
|
43899
|
+
}
|
|
43900
|
+
function labeledInput(label, placeholder, hint) {
|
|
43901
|
+
const wrap = document.createElement("label");
|
|
43902
|
+
wrap.className = "worktree-field";
|
|
43903
|
+
wrap.appendChild(el("span", "", label));
|
|
43904
|
+
const input2 = el("input", "gdp-dialog-input");
|
|
43905
|
+
input2.type = "text";
|
|
43906
|
+
input2.placeholder = placeholder;
|
|
43907
|
+
wrap.appendChild(input2);
|
|
43908
|
+
if (hint) wrap.appendChild(el("span", "worktree-hint", hint));
|
|
43909
|
+
return { wrap, input: input2 };
|
|
43910
|
+
}
|
|
43911
|
+
async function addWorktree() {
|
|
43912
|
+
const seq = lifecycle;
|
|
43913
|
+
const t2 = text3();
|
|
43914
|
+
const body = el("div", "worktree-form");
|
|
43915
|
+
body.appendChild(el("p", "worktree-hint", t2.addDialog.intro));
|
|
43916
|
+
const name = labeledInput(
|
|
43917
|
+
t2.addDialog.nameLabel,
|
|
43918
|
+
t2.addDialog.namePlaceholder
|
|
43919
|
+
);
|
|
43920
|
+
const branch = labeledInput(
|
|
43921
|
+
t2.addDialog.branchLabel,
|
|
43922
|
+
t2.addDialog.branchPlaceholder,
|
|
43923
|
+
t2.addDialog.branchHint
|
|
43924
|
+
);
|
|
43925
|
+
body.append(name.wrap, branch.wrap);
|
|
43926
|
+
const parent = data?.addParent || "";
|
|
43927
|
+
if (parent) {
|
|
43928
|
+
const targetRow = el("div", "worktree-target");
|
|
43929
|
+
targetRow.appendChild(
|
|
43930
|
+
el("span", "worktree-target-label", t2.addDialog.targetLabel)
|
|
43931
|
+
);
|
|
43932
|
+
const targetPath = el("span", "worktree-target-path");
|
|
43933
|
+
targetRow.appendChild(targetPath);
|
|
43934
|
+
const hint = el("span", "worktree-hint-mark", "?");
|
|
43935
|
+
hint.title = t2.gitignoreHint;
|
|
43936
|
+
hint.tabIndex = 0;
|
|
43937
|
+
hint.setAttribute("role", "note");
|
|
43938
|
+
hint.setAttribute(
|
|
43939
|
+
"aria-label",
|
|
43940
|
+
`${t2.addDialog.gitignoreLabel}: ${t2.gitignoreHint}`
|
|
43941
|
+
);
|
|
43942
|
+
targetRow.appendChild(hint);
|
|
43943
|
+
body.appendChild(targetRow);
|
|
43944
|
+
const syncTarget = () => {
|
|
43945
|
+
const value = name.input.value.trim();
|
|
43946
|
+
targetPath.textContent = value ? `${parent}/${value}` : t2.addDialog.targetPending(parent);
|
|
43947
|
+
targetPath.title = targetPath.textContent;
|
|
43948
|
+
};
|
|
43949
|
+
name.input.addEventListener("input", syncTarget);
|
|
43950
|
+
syncTarget();
|
|
43951
|
+
}
|
|
43952
|
+
const submitted = await showFormDialog({
|
|
43953
|
+
title: t2.addDialog.title,
|
|
43954
|
+
body,
|
|
43955
|
+
submitLabel: t2.addDialog.submit,
|
|
43956
|
+
cancelLabel: t2.cancel,
|
|
43957
|
+
focusTarget: name.input,
|
|
43958
|
+
validate: () => {
|
|
43959
|
+
const nameError = worktreeNameError(name.input.value.trim());
|
|
43960
|
+
if (nameError) return t2.nameErrors[nameError];
|
|
43961
|
+
const raw = branch.input.value.trim();
|
|
43962
|
+
if (!raw) return null;
|
|
43963
|
+
const branchError = worktreeBranchError(raw);
|
|
43964
|
+
return branchError ? t2.nameErrors[branchError] : null;
|
|
43965
|
+
},
|
|
43966
|
+
submit: () => ({
|
|
43967
|
+
name: name.input.value.trim(),
|
|
43968
|
+
branch: branch.input.value.trim()
|
|
43969
|
+
})
|
|
43970
|
+
});
|
|
43971
|
+
if (!submitted) return;
|
|
43972
|
+
if (!isCurrent(seq)) return;
|
|
43973
|
+
let createdPath = "";
|
|
43974
|
+
try {
|
|
43975
|
+
const result = await deps.trackLoad(
|
|
43976
|
+
postWorktreeAction("/_worktree/add", submitted)
|
|
43977
|
+
);
|
|
43978
|
+
if (isCurrent(seq)) setMessage("");
|
|
43979
|
+
createdPath = result.path || "";
|
|
43980
|
+
} catch (error2) {
|
|
43981
|
+
if (isCurrent(seq)) {
|
|
43982
|
+
setMessage(error2 instanceof Error ? error2.message : t2.addFailed, true);
|
|
43983
|
+
}
|
|
43984
|
+
}
|
|
43985
|
+
if (isCurrent(seq) && createdPath) {
|
|
43986
|
+
navigate({ wt: createdPath });
|
|
43987
|
+
}
|
|
43988
|
+
if (isCurrent(seq)) await refresh();
|
|
43989
|
+
}
|
|
43990
|
+
async function removeWorktree(item) {
|
|
43991
|
+
if (busyPath) return;
|
|
43992
|
+
const seq = lifecycle;
|
|
43993
|
+
const t2 = text3();
|
|
43994
|
+
const body = el("div", "worktree-form");
|
|
43995
|
+
if (item.missing) {
|
|
43996
|
+
body.appendChild(el("p", "", t2.removeDialog.missingBody(item.name)));
|
|
43997
|
+
body.appendChild(el("p", "worktree-hint", t2.removeDialog.missingNote));
|
|
43998
|
+
if (item.locked) {
|
|
43999
|
+
body.appendChild(el("p", "worktree-warn", t2.removeDialog.lockedNote));
|
|
44000
|
+
}
|
|
44001
|
+
const otherMissing = (data?.worktrees || []).filter(
|
|
44002
|
+
(candidate) => candidate.missing && !candidate.locked && candidate.id !== item.id
|
|
44003
|
+
).length;
|
|
44004
|
+
if (otherMissing > 0) {
|
|
44005
|
+
body.appendChild(
|
|
44006
|
+
el("p", "worktree-hint", t2.removeDialog.missingOthers(otherMissing))
|
|
44007
|
+
);
|
|
44008
|
+
}
|
|
44009
|
+
} else {
|
|
44010
|
+
body.appendChild(el("p", "", t2.removeDialog.body(item.name)));
|
|
44011
|
+
body.appendChild(el("p", "", t2.removeDialog.diskNote(item.path)));
|
|
44012
|
+
}
|
|
44013
|
+
if (item.branch) {
|
|
44014
|
+
body.appendChild(
|
|
44015
|
+
el("p", "worktree-hint", t2.removeDialog.branchNote(item.branch))
|
|
44016
|
+
);
|
|
44017
|
+
}
|
|
44018
|
+
let force = null;
|
|
44019
|
+
if (!item.missing && item.changedCount > 0) {
|
|
44020
|
+
const warn = el("p", "worktree-warn");
|
|
44021
|
+
warn.appendChild(
|
|
44022
|
+
el("span", "", `⚠ ${t2.removeDialog.dirtyNote(item.changedCount)}`)
|
|
44023
|
+
);
|
|
44024
|
+
warn.appendChild(document.createElement("br"));
|
|
44025
|
+
warn.appendChild(el("span", "", t2.removeDialog.dirtyLose));
|
|
44026
|
+
body.appendChild(warn);
|
|
44027
|
+
const forceWrap = document.createElement("label");
|
|
44028
|
+
forceWrap.className = "worktree-check";
|
|
44029
|
+
force = document.createElement("input");
|
|
44030
|
+
force.type = "checkbox";
|
|
44031
|
+
forceWrap.append(force, el("span", "", t2.removeDialog.force));
|
|
44032
|
+
body.appendChild(forceWrap);
|
|
44033
|
+
}
|
|
44034
|
+
const submitted = await showFormDialog({
|
|
44035
|
+
title: t2.removeDialog.title,
|
|
44036
|
+
body,
|
|
44037
|
+
submitLabel: t2.removeDialog.submit,
|
|
44038
|
+
cancelLabel: t2.cancel,
|
|
44039
|
+
// フォルダごと消える不可逆の操作なので、確定は常に危険色。
|
|
44040
|
+
danger: true,
|
|
44041
|
+
validate: () => force && !force.checked ? t2.removeDialog.forceRequired : null,
|
|
44042
|
+
submit: () => ({ force: force?.checked ?? false })
|
|
44043
|
+
});
|
|
44044
|
+
if (!submitted) return;
|
|
44045
|
+
if (!isCurrent(seq)) return;
|
|
44046
|
+
busyPath = item.path;
|
|
44047
|
+
renderList();
|
|
44048
|
+
try {
|
|
44049
|
+
await deps.trackLoad(
|
|
44050
|
+
postWorktreeAction("/_worktree/remove", {
|
|
44051
|
+
path: item.path,
|
|
44052
|
+
force: submitted.force
|
|
44053
|
+
})
|
|
44054
|
+
);
|
|
44055
|
+
if (isCurrent(seq)) setMessage("");
|
|
44056
|
+
if (isCurrent(seq) && route()?.wt === item.id) {
|
|
44057
|
+
navigate({ wt: void 0, file: void 0, origin: void 0 }, true);
|
|
44058
|
+
}
|
|
44059
|
+
} catch (error2) {
|
|
44060
|
+
if (isCurrent(seq)) {
|
|
44061
|
+
setMessage(
|
|
44062
|
+
error2 instanceof Error ? error2.message : t2.removeFailed,
|
|
44063
|
+
true
|
|
44064
|
+
);
|
|
44065
|
+
}
|
|
44066
|
+
} finally {
|
|
44067
|
+
busyPath = "";
|
|
44068
|
+
if (isCurrent(seq)) await refresh();
|
|
44069
|
+
}
|
|
44070
|
+
}
|
|
44071
|
+
function overlapOthers(item, file) {
|
|
44072
|
+
const paths = new Set([file.path, file.oldPath].filter(Boolean));
|
|
44073
|
+
const ownerIds = new Set(
|
|
44074
|
+
(data?.overlaps || []).filter((overlap) => paths.has(overlap.path)).flatMap((overlap) => overlap.worktreeIds)
|
|
44075
|
+
);
|
|
44076
|
+
return [...ownerIds].filter((id) => id !== item.id).map((id) => worktreeLabel(id));
|
|
44077
|
+
}
|
|
44078
|
+
function divergenceSummary(item) {
|
|
44079
|
+
const t2 = text3();
|
|
44080
|
+
const divergence = item.divergence;
|
|
44081
|
+
if (!divergence) return t2.diverge.notComparable;
|
|
44082
|
+
const parts = [];
|
|
44083
|
+
if (divergence.mergeState === "clean") {
|
|
44084
|
+
parts.push(t2.merge.clean);
|
|
44085
|
+
} else if (divergence.mergeState === "conflict") {
|
|
44086
|
+
parts.push(t2.merge.conflict(divergence.conflicts.length));
|
|
44087
|
+
} else {
|
|
44088
|
+
parts.push(t2.merge.unknown);
|
|
44089
|
+
}
|
|
44090
|
+
if (divergence.ahead > 0) {
|
|
44091
|
+
parts.push(t2.diverge.ahead(divergence.ahead, divergence.base));
|
|
44092
|
+
}
|
|
44093
|
+
if (divergence.behind > 0) {
|
|
44094
|
+
parts.push(t2.diverge.behind(divergence.behind, divergence.base));
|
|
44095
|
+
}
|
|
44096
|
+
if (!divergence.ahead && !divergence.behind) {
|
|
44097
|
+
parts.push(t2.diverge.even(divergence.base));
|
|
44098
|
+
}
|
|
44099
|
+
return parts.join(" · ");
|
|
44100
|
+
}
|
|
44101
|
+
function worktreeBadges(item) {
|
|
44102
|
+
const t2 = text3();
|
|
44103
|
+
const badges = [];
|
|
44104
|
+
if (item.current) {
|
|
44105
|
+
badges.push({ label: t2.badges.current, title: t2.badges.currentTitle });
|
|
44106
|
+
}
|
|
44107
|
+
if (item.serverUrl) {
|
|
44108
|
+
badges.push({ label: t2.badges.running, title: t2.badges.runningTitle });
|
|
44109
|
+
}
|
|
44110
|
+
if (item.missing) badges.push({ label: t2.badges.missing, title: "" });
|
|
44111
|
+
if (item.bare) {
|
|
44112
|
+
badges.push({ label: t2.badges.bare, title: t2.badges.bareTitle });
|
|
44113
|
+
}
|
|
44114
|
+
if (item.locked) {
|
|
44115
|
+
badges.push({ label: t2.badges.locked, title: item.lockedReason });
|
|
44116
|
+
}
|
|
44117
|
+
if (item.prunable) {
|
|
44118
|
+
badges.push({ label: t2.badges.prunable, title: t2.badges.prunableTitle });
|
|
44119
|
+
}
|
|
44120
|
+
return badges;
|
|
44121
|
+
}
|
|
44122
|
+
function headButton(label, title, onClick) {
|
|
44123
|
+
const button = el("button", "gdp-btn gdp-btn-sm worktree-head-btn", label);
|
|
44124
|
+
button.type = "button";
|
|
44125
|
+
button.title = title;
|
|
44126
|
+
button.addEventListener("click", onClick);
|
|
44127
|
+
return button;
|
|
44128
|
+
}
|
|
44129
|
+
function openFolderButton(item, withLabel) {
|
|
44130
|
+
const arg = openPathArg(item);
|
|
44131
|
+
if (arg === null) return null;
|
|
44132
|
+
const t2 = text3();
|
|
44133
|
+
const button = deps.createOpenPathButton(
|
|
44134
|
+
arg,
|
|
44135
|
+
"directory",
|
|
44136
|
+
t2.actions.openFolderTitle
|
|
44137
|
+
);
|
|
44138
|
+
if (withLabel) {
|
|
44139
|
+
button.className = "gdp-btn gdp-btn-sm gdp-open-path";
|
|
44140
|
+
button.textContent = t2.actions.openFolder;
|
|
44141
|
+
}
|
|
44142
|
+
return button;
|
|
44143
|
+
}
|
|
44144
|
+
function copyButton(value, title, label) {
|
|
44145
|
+
const button = el(
|
|
44146
|
+
"button",
|
|
44147
|
+
label ? "gdp-btn gdp-btn-sm gdp-copy-path" : "gdp-file-header-icon gdp-copy-path",
|
|
44148
|
+
label
|
|
44149
|
+
);
|
|
44150
|
+
button.type = "button";
|
|
44151
|
+
button.title = title;
|
|
44152
|
+
button.setAttribute("aria-label", title);
|
|
44153
|
+
if (!label) button.innerHTML = iconSvg("octicon-copy", COPY_16_PATHS);
|
|
44154
|
+
button.addEventListener("click", async (event) => {
|
|
44155
|
+
event.stopPropagation();
|
|
44156
|
+
button.classList.remove("copied", "failed");
|
|
44157
|
+
button.classList.add(await copyText(value) ? "copied" : "failed");
|
|
44158
|
+
window.setTimeout(
|
|
44159
|
+
() => button.classList.remove("copied", "failed"),
|
|
44160
|
+
1200
|
|
44161
|
+
);
|
|
44162
|
+
});
|
|
44163
|
+
return button;
|
|
44164
|
+
}
|
|
44165
|
+
async function runAction(run, failure) {
|
|
44166
|
+
const seq = lifecycle;
|
|
44167
|
+
if (await run()) return;
|
|
44168
|
+
if (!isCurrent(seq)) return;
|
|
44169
|
+
setMessage(failure, true);
|
|
44170
|
+
renderList();
|
|
44171
|
+
}
|
|
44172
|
+
async function copyText(value) {
|
|
44173
|
+
try {
|
|
44174
|
+
await navigator.clipboard.writeText(value);
|
|
44175
|
+
return true;
|
|
44176
|
+
} catch (error2) {
|
|
44177
|
+
console.error("[code-viewer] failed to copy to clipboard", error2);
|
|
44178
|
+
return false;
|
|
44179
|
+
}
|
|
44180
|
+
}
|
|
44181
|
+
function copyPathButton(item, withLabel) {
|
|
44182
|
+
const t2 = text3();
|
|
44183
|
+
return copyButton(
|
|
44184
|
+
item.path,
|
|
44185
|
+
t2.actions.copyPathTitle,
|
|
44186
|
+
withLabel ? t2.actions.copyPath : void 0
|
|
44187
|
+
);
|
|
44188
|
+
}
|
|
44189
|
+
function mergeCommand(item) {
|
|
44190
|
+
const divergence = item.divergence;
|
|
44191
|
+
if (!divergence || divergence.mergeState !== "clean") return null;
|
|
44192
|
+
if (!item.branch || !divergence.base) return null;
|
|
44193
|
+
return {
|
|
44194
|
+
base: divergence.base,
|
|
44195
|
+
branch: item.branch,
|
|
44196
|
+
command: `git switch ${divergence.base} && git merge ${item.branch}`
|
|
44197
|
+
};
|
|
44198
|
+
}
|
|
44199
|
+
function copyMergeButton(item) {
|
|
44200
|
+
const merge = mergeCommand(item);
|
|
44201
|
+
if (!merge) return null;
|
|
44202
|
+
const t2 = text3();
|
|
44203
|
+
return copyButton(
|
|
44204
|
+
merge.command,
|
|
44205
|
+
t2.actions.copyMergeTitle(merge.base, merge.branch)
|
|
44206
|
+
);
|
|
44207
|
+
}
|
|
44208
|
+
async function stopWorktreeServer(item) {
|
|
44209
|
+
if (busyPath) return;
|
|
44210
|
+
const seq = lifecycle;
|
|
44211
|
+
busyPath = item.path;
|
|
44212
|
+
renderList();
|
|
44213
|
+
try {
|
|
44214
|
+
await deps.trackLoad(
|
|
44215
|
+
postWorktreeAction("/_worktree/stop", { path: item.path })
|
|
44216
|
+
);
|
|
44217
|
+
if (isCurrent(seq)) setMessage("");
|
|
44218
|
+
} catch (error2) {
|
|
44219
|
+
if (isCurrent(seq)) {
|
|
44220
|
+
setMessage(
|
|
44221
|
+
error2 instanceof Error ? error2.message : text3().actions.stopFailed,
|
|
44222
|
+
true
|
|
44223
|
+
);
|
|
44224
|
+
}
|
|
44225
|
+
} finally {
|
|
44226
|
+
busyPath = "";
|
|
44227
|
+
if (isCurrent(seq)) await refresh();
|
|
44228
|
+
}
|
|
44229
|
+
}
|
|
44230
|
+
function openPathArg(item) {
|
|
44231
|
+
const shown = item.displayPath;
|
|
44232
|
+
if (shown === ".") return "";
|
|
44233
|
+
if (!shown || shown.startsWith("/") || shown.startsWith("\\")) return null;
|
|
44234
|
+
return shown;
|
|
44235
|
+
}
|
|
44236
|
+
function rowMenuItems(item) {
|
|
44237
|
+
const t2 = text3();
|
|
44238
|
+
const items = [];
|
|
44239
|
+
if (!item.missing && !item.bare) {
|
|
44240
|
+
const openArg = openPathArg(item);
|
|
44241
|
+
if (openArg !== null) {
|
|
44242
|
+
items.push({
|
|
44243
|
+
label: t2.actions.openFolder,
|
|
44244
|
+
title: t2.actions.openFolderTitle,
|
|
44245
|
+
onSelect: () => {
|
|
44246
|
+
void runAction(
|
|
44247
|
+
() => deps.openPathInOs(openArg, "directory"),
|
|
44248
|
+
t2.actions.openFolderFailed
|
|
44249
|
+
);
|
|
44250
|
+
}
|
|
44251
|
+
});
|
|
44252
|
+
}
|
|
44253
|
+
items.push({
|
|
44254
|
+
label: t2.actions.copyPath,
|
|
44255
|
+
title: t2.actions.copyPathTitle,
|
|
44256
|
+
onSelect: () => {
|
|
44257
|
+
void runAction(() => copyText(item.path), t2.actions.copyFailed);
|
|
44258
|
+
}
|
|
44259
|
+
});
|
|
44260
|
+
items.push({
|
|
44261
|
+
label: t2.open,
|
|
44262
|
+
title: t2.openTitle,
|
|
44263
|
+
disabled: !!busyPath,
|
|
44264
|
+
onSelect: () => {
|
|
44265
|
+
void openWorktree(item);
|
|
44266
|
+
}
|
|
44267
|
+
});
|
|
44268
|
+
}
|
|
44269
|
+
if (item.serverUrl) {
|
|
44270
|
+
items.push({
|
|
44271
|
+
label: t2.actions.copyServerUrl,
|
|
44272
|
+
title: t2.actions.copyServerUrlTitle(item.serverUrl),
|
|
44273
|
+
onSelect: () => {
|
|
44274
|
+
void runAction(() => copyText(item.serverUrl), t2.actions.copyFailed);
|
|
44275
|
+
}
|
|
44276
|
+
});
|
|
44277
|
+
}
|
|
44278
|
+
if (item.serverUrl && !item.current) {
|
|
44279
|
+
items.push({
|
|
44280
|
+
label: t2.actions.stopServer,
|
|
44281
|
+
title: t2.actions.stopServerTitle,
|
|
44282
|
+
disabled: !!busyPath,
|
|
44283
|
+
onSelect: () => {
|
|
44284
|
+
void stopWorktreeServer(item);
|
|
44285
|
+
}
|
|
44286
|
+
});
|
|
44287
|
+
}
|
|
44288
|
+
const merge = mergeCommand(item);
|
|
44289
|
+
if (merge) {
|
|
44290
|
+
items.push({
|
|
44291
|
+
label: t2.actions.copyMerge,
|
|
44292
|
+
title: t2.actions.copyMergeTitle(merge.base, merge.branch),
|
|
44293
|
+
onSelect: () => {
|
|
44294
|
+
void runAction(() => copyText(merge.command), t2.actions.copyFailed);
|
|
44295
|
+
}
|
|
44296
|
+
});
|
|
44297
|
+
}
|
|
44298
|
+
if (!item.current) {
|
|
44299
|
+
if (items.length) items.push({ kind: "separator" });
|
|
44300
|
+
items.push({
|
|
44301
|
+
label: t2.remove,
|
|
44302
|
+
title: t2.removeTitle,
|
|
44303
|
+
danger: true,
|
|
44304
|
+
disabled: !!busyPath,
|
|
44305
|
+
onSelect: () => {
|
|
44306
|
+
void removeWorktree(item);
|
|
44307
|
+
}
|
|
44308
|
+
});
|
|
44309
|
+
}
|
|
44310
|
+
return items;
|
|
44311
|
+
}
|
|
44312
|
+
function rowMenuButton(item) {
|
|
44313
|
+
const items = rowMenuItems(item);
|
|
44314
|
+
if (!items.length) return null;
|
|
44315
|
+
const t2 = text3();
|
|
44316
|
+
const button = el("button", "worktree-row-menu");
|
|
44317
|
+
button.type = "button";
|
|
44318
|
+
button.title = t2.actions.menuTitle;
|
|
44319
|
+
button.setAttribute("aria-label", t2.actions.menuFor(item.name));
|
|
44320
|
+
button.setAttribute("aria-haspopup", "menu");
|
|
44321
|
+
button.innerHTML = iconSvg("octicon-kebab-horizontal", KEBAB_16_PATH);
|
|
44322
|
+
button.addEventListener("click", (event) => {
|
|
44323
|
+
event.stopPropagation();
|
|
44324
|
+
showContextMenu(button, rowMenuItems(item));
|
|
44325
|
+
});
|
|
44326
|
+
return button;
|
|
44327
|
+
}
|
|
44328
|
+
function note(body, isError = false) {
|
|
44329
|
+
const node = el("div", "history-status", body);
|
|
44330
|
+
node.hidden = false;
|
|
44331
|
+
if (isError) {
|
|
44332
|
+
node.setAttribute("role", "alert");
|
|
44333
|
+
node.style.color = "var(--danger)";
|
|
44334
|
+
}
|
|
44335
|
+
return node;
|
|
44336
|
+
}
|
|
44337
|
+
function renderList() {
|
|
44338
|
+
if (!listPanel) return;
|
|
44339
|
+
const t2 = text3();
|
|
44340
|
+
listPanel.replaceChildren();
|
|
44341
|
+
const head = el("div", "history-head");
|
|
44342
|
+
head.appendChild(el("span", "history-title", t2.panes.worktrees));
|
|
44343
|
+
head.appendChild(
|
|
44344
|
+
headButton(t2.refresh, t2.refreshTitle, () => {
|
|
44345
|
+
void refresh();
|
|
44346
|
+
})
|
|
44347
|
+
);
|
|
44348
|
+
head.appendChild(
|
|
44349
|
+
headButton(t2.add, t2.addTitle, () => {
|
|
44350
|
+
void addWorktree();
|
|
44351
|
+
})
|
|
44352
|
+
);
|
|
44353
|
+
listPanel.appendChild(head);
|
|
44354
|
+
worktreeFilterInput.placeholder = t2.panes.filterWorktrees;
|
|
44355
|
+
const filterWrap = el("div", "history-filter-wrap");
|
|
44356
|
+
filterWrap.appendChild(worktreeFilterInput);
|
|
44357
|
+
listPanel.appendChild(filterWrap);
|
|
44358
|
+
if (data && !data.baseBranch) {
|
|
44359
|
+
listPanel.appendChild(note(t2.baseUnknown));
|
|
44360
|
+
}
|
|
44361
|
+
if (message) listPanel.appendChild(note(message, messageIsError));
|
|
44362
|
+
const overlaps = data?.overlaps || [];
|
|
44363
|
+
if (overlaps.length) {
|
|
44364
|
+
const banner = el("div", "history-banner");
|
|
44365
|
+
banner.hidden = false;
|
|
44366
|
+
banner.textContent = `${t2.overlaps.heading(overlaps.length)} — ${t2.overlaps.intro}`;
|
|
44367
|
+
banner.title = overlaps.map(
|
|
44368
|
+
(overlap) => t2.overlaps.entry(
|
|
44369
|
+
overlap.path,
|
|
44370
|
+
overlap.worktreeIds.map((id) => worktreeLabel(id))
|
|
44371
|
+
)
|
|
44372
|
+
).join("\n");
|
|
44373
|
+
listPanel.appendChild(banner);
|
|
44374
|
+
}
|
|
44375
|
+
if (!data) {
|
|
44376
|
+
listPanel.appendChild(note(t2.loading));
|
|
44377
|
+
return;
|
|
44378
|
+
}
|
|
44379
|
+
if (!data.worktrees.length) {
|
|
44380
|
+
listPanel.appendChild(note(t2.empty));
|
|
44381
|
+
return;
|
|
44382
|
+
}
|
|
44383
|
+
const items = data.worktrees.filter(
|
|
44384
|
+
(item) => matches(item.name, worktreeFilter) || matches(item.branch, worktreeFilter) || matches(item.displayPath, worktreeFilter)
|
|
44385
|
+
);
|
|
44386
|
+
if (!items.length) {
|
|
44387
|
+
listPanel.appendChild(note(t2.panes.noWorktreeMatch));
|
|
44388
|
+
return;
|
|
44389
|
+
}
|
|
44390
|
+
const list2 = el("ol", "history-list");
|
|
44391
|
+
const selected = route()?.wt;
|
|
44392
|
+
for (const item of items) {
|
|
44393
|
+
const row = el("li", "history-item");
|
|
44394
|
+
row.dataset.wt = item.id;
|
|
44395
|
+
if (item.id === selected) row.classList.add("active");
|
|
44396
|
+
if (item.divergence?.mergeState === "conflict") {
|
|
44397
|
+
row.classList.add("worktree-conflict");
|
|
44398
|
+
}
|
|
44399
|
+
const head2 = el("span", "worktree-row-head");
|
|
44400
|
+
const subject = el("span", "subject", item.name);
|
|
44401
|
+
subject.title = item.path;
|
|
44402
|
+
head2.appendChild(subject);
|
|
44403
|
+
const badges = worktreeBadges(item);
|
|
44404
|
+
if (badges.length) {
|
|
44405
|
+
const wrap = el("span", "worktree-row-badges");
|
|
44406
|
+
badges.forEach((badge, index) => {
|
|
44407
|
+
if (index) wrap.appendChild(document.createTextNode(" · "));
|
|
44408
|
+
const node = el("span", "worktree-badge", badge.label);
|
|
44409
|
+
node.title = badge.title;
|
|
44410
|
+
wrap.appendChild(node);
|
|
44411
|
+
});
|
|
44412
|
+
head2.appendChild(wrap);
|
|
44413
|
+
}
|
|
44414
|
+
const menu = rowMenuButton(item);
|
|
44415
|
+
if (menu) head2.appendChild(menu);
|
|
44416
|
+
row.appendChild(head2);
|
|
44417
|
+
const pathLine = el("span", "worktree-row-path", item.path);
|
|
44418
|
+
pathLine.title = item.path;
|
|
44419
|
+
row.appendChild(pathLine);
|
|
44420
|
+
const meta = el("span", "meta2");
|
|
44421
|
+
const branchName = el("span", "sha", item.branch || t2.badges.detached);
|
|
44422
|
+
if (!item.branch) branchName.title = t2.badges.detachedTitle;
|
|
44423
|
+
meta.appendChild(branchName);
|
|
44424
|
+
meta.appendChild(
|
|
44425
|
+
el(
|
|
44426
|
+
"span",
|
|
44427
|
+
"author",
|
|
44428
|
+
item.fileCount ? t2.files.heading(item.fileCount) : t2.files.none
|
|
44429
|
+
)
|
|
44430
|
+
);
|
|
44431
|
+
if (item.lastCommit) {
|
|
44432
|
+
const parsed = Date.parse(item.lastCommit.when);
|
|
44433
|
+
const when = el(
|
|
44434
|
+
"span",
|
|
44435
|
+
"when",
|
|
44436
|
+
Number.isFinite(parsed) ? blameRelativeTime(Math.round(parsed / 1e3)) : item.lastCommit.when
|
|
44437
|
+
);
|
|
44438
|
+
when.title = Number.isFinite(parsed) ? `${item.lastCommit.subject}
|
|
44439
|
+
${new Date(parsed).toLocaleString()}` : item.lastCommit.subject;
|
|
44440
|
+
meta.appendChild(when);
|
|
44441
|
+
}
|
|
44442
|
+
if (item.lastTouched) {
|
|
44443
|
+
const parsed = Date.parse(item.lastTouched);
|
|
44444
|
+
const when = el(
|
|
44445
|
+
"span",
|
|
44446
|
+
"when",
|
|
44447
|
+
Number.isFinite(parsed) ? t2.lastTouched(blameRelativeTime(Math.round(parsed / 1e3))) : t2.lastTouched(item.lastTouched)
|
|
44448
|
+
);
|
|
44449
|
+
when.title = Number.isFinite(parsed) ? new Date(parsed).toLocaleString() : item.lastTouched;
|
|
44450
|
+
meta.appendChild(when);
|
|
44451
|
+
}
|
|
44452
|
+
row.appendChild(meta);
|
|
44453
|
+
const second = el("span", "meta2");
|
|
44454
|
+
const summary = divergenceSummary(item);
|
|
44455
|
+
const summaryText = el("span", "author", summary);
|
|
44456
|
+
summaryText.title = summary;
|
|
44457
|
+
second.appendChild(summaryText);
|
|
44458
|
+
const merge = copyMergeButton(item);
|
|
44459
|
+
if (merge) second.appendChild(merge);
|
|
44460
|
+
row.appendChild(second);
|
|
44461
|
+
if (item.error) {
|
|
44462
|
+
const error2 = el("span", "meta2");
|
|
44463
|
+
const detail = el("span", "author", item.error);
|
|
44464
|
+
detail.style.color = "var(--danger)";
|
|
44465
|
+
error2.appendChild(detail);
|
|
44466
|
+
row.appendChild(error2);
|
|
44467
|
+
}
|
|
44468
|
+
list2.appendChild(row);
|
|
44469
|
+
}
|
|
44470
|
+
list2.addEventListener("click", (event) => {
|
|
44471
|
+
const row = event.target?.closest(
|
|
44472
|
+
".history-item"
|
|
44473
|
+
);
|
|
44474
|
+
const id = row?.dataset.wt;
|
|
44475
|
+
if (!id) return;
|
|
44476
|
+
navigate({ wt: id, file: void 0, origin: void 0 });
|
|
44477
|
+
});
|
|
44478
|
+
listPanel.appendChild(list2);
|
|
44479
|
+
if (data.worktrees.length === 1) {
|
|
44480
|
+
listPanel.appendChild(note(t2.intro.listNote));
|
|
44481
|
+
}
|
|
44482
|
+
}
|
|
44483
|
+
function introCard() {
|
|
44484
|
+
const t2 = text3();
|
|
44485
|
+
const card = el("div", "worktree-intro");
|
|
44486
|
+
card.appendChild(el("p", "worktree-intro-title", t2.intro.cardTitle));
|
|
44487
|
+
card.appendChild(el("p", "", t2.intro.cardWhat));
|
|
44488
|
+
card.appendChild(el("p", "", t2.intro.cardWhy));
|
|
44489
|
+
card.appendChild(el("p", "", t2.intro.cardHow));
|
|
44490
|
+
const button = el("button", "gdp-btn gdp-btn-sm", t2.intro.cardButton);
|
|
44491
|
+
button.type = "button";
|
|
44492
|
+
button.addEventListener("click", () => {
|
|
44493
|
+
void addWorktree();
|
|
44494
|
+
});
|
|
44495
|
+
card.appendChild(button);
|
|
44496
|
+
return card;
|
|
44497
|
+
}
|
|
44498
|
+
function visibleFiles(item) {
|
|
44499
|
+
const hideTests = deps.getOptions().hideTests;
|
|
44500
|
+
return item.files.filter(
|
|
44501
|
+
(file) => matches(file.path, fileFilter) && !(hideTests && deps.isTestPath(file.path))
|
|
44502
|
+
);
|
|
44503
|
+
}
|
|
44504
|
+
function emptyTree() {
|
|
44505
|
+
return { dirs: /* @__PURE__ */ new Map(), files: [] };
|
|
44506
|
+
}
|
|
44507
|
+
function buildTree(files) {
|
|
44508
|
+
const root = emptyTree();
|
|
44509
|
+
for (const file of files) {
|
|
44510
|
+
const parts = file.path.split("/");
|
|
44511
|
+
let node = root;
|
|
44512
|
+
for (let i2 = 0; i2 < parts.length - 1; i2++) {
|
|
44513
|
+
const name = parts[i2];
|
|
44514
|
+
let child = node.dirs.get(name);
|
|
44515
|
+
if (!child) {
|
|
44516
|
+
child = emptyTree();
|
|
44517
|
+
node.dirs.set(name, child);
|
|
44518
|
+
}
|
|
44519
|
+
node = child;
|
|
44520
|
+
}
|
|
44521
|
+
node.files.push(file);
|
|
44522
|
+
}
|
|
44523
|
+
return root;
|
|
44524
|
+
}
|
|
44525
|
+
function collapseChain(name, node) {
|
|
44526
|
+
let label = name;
|
|
44527
|
+
let current = node;
|
|
44528
|
+
while (current.files.length === 0 && current.dirs.size === 1) {
|
|
44529
|
+
const [childName, child] = [...current.dirs.entries()][0];
|
|
44530
|
+
label = `${label}/${childName}`;
|
|
44531
|
+
current = child;
|
|
44532
|
+
}
|
|
44533
|
+
return [label, current];
|
|
44534
|
+
}
|
|
44535
|
+
function fileRow(item, file, depth, label) {
|
|
44536
|
+
const t2 = text3();
|
|
44537
|
+
const row = el("li", "tree-file");
|
|
44538
|
+
row.tabIndex = -1;
|
|
44539
|
+
row.dataset.path = file.path;
|
|
44540
|
+
row.dataset.key = fileKey(file);
|
|
44541
|
+
row.dataset.type = "blob";
|
|
44542
|
+
const currentRoute = route();
|
|
44543
|
+
if (currentRoute?.file === file.path && currentRoute.origin === file.origin) {
|
|
44544
|
+
row.classList.add("active");
|
|
44545
|
+
}
|
|
44546
|
+
row.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
|
|
44547
|
+
row.appendChild(el("span", "chev-spacer"));
|
|
44548
|
+
const badge = el("span", `badge ${file.status}`, file.status);
|
|
44549
|
+
badge.title = t2.files.statusTitles[file.status] || file.status;
|
|
44550
|
+
row.appendChild(badge);
|
|
44551
|
+
const name = el("span", "name", label);
|
|
44552
|
+
name.title = file.path;
|
|
44553
|
+
row.appendChild(name);
|
|
44554
|
+
const others = overlapOthers(item, file);
|
|
44555
|
+
if (others.length) {
|
|
44556
|
+
row.classList.add("worktree-overlap");
|
|
44557
|
+
const mark = el(
|
|
44558
|
+
"span",
|
|
44559
|
+
"stat worktree-overlap-count",
|
|
44560
|
+
String(others.length)
|
|
44561
|
+
);
|
|
44562
|
+
mark.title = t2.files.overlapTitle(others);
|
|
44563
|
+
row.appendChild(mark);
|
|
44564
|
+
name.title = `${file.path}
|
|
44565
|
+
${t2.files.overlapTitle(others)}`;
|
|
44566
|
+
}
|
|
44567
|
+
return row;
|
|
44568
|
+
}
|
|
44569
|
+
function renderTreeInto(parent, item, node, depth) {
|
|
44570
|
+
for (const [rawName, rawChild] of node.dirs) {
|
|
44571
|
+
const [label, child] = collapseChain(rawName, rawChild);
|
|
44572
|
+
const li = el("li", "tree-dir");
|
|
44573
|
+
li.tabIndex = -1;
|
|
44574
|
+
li.dataset.type = "tree";
|
|
44575
|
+
li.style.setProperty("--lvl-pad", `${12 + depth * 14}px`);
|
|
44576
|
+
const chev = el("span", "chev");
|
|
44577
|
+
chev.innerHTML = chevronSvg();
|
|
44578
|
+
const icon = el("span", "dir-icon");
|
|
44579
|
+
icon.innerHTML = folderSvg(false);
|
|
44580
|
+
const name = el("span", "name", label);
|
|
44581
|
+
name.title = label;
|
|
44582
|
+
li.append(chev, icon, name);
|
|
44583
|
+
const toggle = (event) => {
|
|
44584
|
+
event.stopPropagation();
|
|
44585
|
+
const collapsed = li.classList.toggle("collapsed");
|
|
44586
|
+
icon.innerHTML = folderSvg(collapsed);
|
|
44587
|
+
};
|
|
44588
|
+
chev.addEventListener("click", toggle);
|
|
44589
|
+
icon.addEventListener("click", toggle);
|
|
44590
|
+
parent.appendChild(li);
|
|
44591
|
+
const children = el("ul", "tree-children");
|
|
44592
|
+
renderTreeInto(children, item, child, depth + 1);
|
|
44593
|
+
parent.appendChild(children);
|
|
44594
|
+
}
|
|
44595
|
+
for (const file of node.files) {
|
|
44596
|
+
const parts = file.path.split("/");
|
|
44597
|
+
parent.appendChild(
|
|
44598
|
+
fileRow(item, file, depth, parts[parts.length - 1] || file.path)
|
|
44599
|
+
);
|
|
44600
|
+
}
|
|
44601
|
+
}
|
|
44602
|
+
function renderFiles() {
|
|
44603
|
+
const t2 = text3();
|
|
44604
|
+
const list2 = document.getElementById("filelist");
|
|
44605
|
+
const title = document.querySelector(".sb-title");
|
|
44606
|
+
const totals = document.getElementById("totals");
|
|
44607
|
+
if (!list2) return;
|
|
44608
|
+
const tree = deps.getSidebarView() === "tree";
|
|
44609
|
+
list2.classList.toggle("tree", tree);
|
|
44610
|
+
for (const button of sidebarViewButtons()) {
|
|
44611
|
+
const active = button.dataset.view === (tree ? "tree" : "flat");
|
|
44612
|
+
button.classList.toggle("active", active);
|
|
44613
|
+
button.setAttribute("aria-pressed", String(active));
|
|
44614
|
+
}
|
|
44615
|
+
for (const button of document.querySelectorAll(
|
|
44616
|
+
".sb-tree-action"
|
|
44617
|
+
)) {
|
|
44618
|
+
button.disabled = !tree;
|
|
44619
|
+
}
|
|
44620
|
+
if (title) title.textContent = t2.panes.files;
|
|
44621
|
+
const item = selectedWorktree();
|
|
44622
|
+
if (totals) {
|
|
44623
|
+
totals.textContent = item ? t2.files.heading(item.fileCount) : "";
|
|
44624
|
+
}
|
|
44625
|
+
list2.replaceChildren();
|
|
44626
|
+
if (!item) {
|
|
44627
|
+
list2.appendChild(note(t2.panes.selectWorktree));
|
|
44628
|
+
return;
|
|
44629
|
+
}
|
|
44630
|
+
if (!item.fileCount) {
|
|
44631
|
+
list2.appendChild(note(t2.files.none));
|
|
44632
|
+
return;
|
|
44633
|
+
}
|
|
44634
|
+
const shown = visibleFiles(item);
|
|
44635
|
+
if (!shown.length) {
|
|
44636
|
+
list2.appendChild(note(t2.panes.noFileMatch));
|
|
44637
|
+
return;
|
|
44638
|
+
}
|
|
44639
|
+
if (shown.some((entry) => overlapOthers(item, entry).length > 0)) {
|
|
44640
|
+
list2.appendChild(
|
|
44641
|
+
el("li", "worktree-overlap-legend", t2.intro.overlapLegend)
|
|
44642
|
+
);
|
|
44643
|
+
}
|
|
44644
|
+
for (const group of ["uncommitted", "committed"]) {
|
|
44645
|
+
const files = shown.filter((file) => file.origin === group);
|
|
44646
|
+
if (!files.length) continue;
|
|
44647
|
+
list2.appendChild(
|
|
44648
|
+
el(
|
|
44649
|
+
"li",
|
|
44650
|
+
"worktree-file-group",
|
|
44651
|
+
group === "uncommitted" ? t2.files.uncommitted : t2.files.committed
|
|
44652
|
+
)
|
|
44653
|
+
);
|
|
44654
|
+
if (tree) renderTreeInto(list2, item, buildTree(files), 0);
|
|
44655
|
+
else {
|
|
44656
|
+
for (const file of files) {
|
|
44657
|
+
list2.appendChild(fileRow(item, file, 0, file.path));
|
|
44658
|
+
}
|
|
44659
|
+
}
|
|
44660
|
+
}
|
|
44661
|
+
}
|
|
44662
|
+
function onFileListClick(event) {
|
|
44663
|
+
const row = event.target?.closest(
|
|
44664
|
+
".tree-file"
|
|
44665
|
+
);
|
|
44666
|
+
const key = row?.dataset.key;
|
|
44667
|
+
if (!key) return;
|
|
44668
|
+
const shell = document.querySelector(
|
|
44669
|
+
`#diff .gdp-file-shell[data-key="${CSS.escape(key)}"]`
|
|
44670
|
+
);
|
|
44671
|
+
restoredRouteKey = key;
|
|
44672
|
+
shell?.scrollIntoView({ block: "start" });
|
|
44673
|
+
const [origin, ...rest] = key.split(":");
|
|
44674
|
+
navigate(
|
|
44675
|
+
{
|
|
44676
|
+
file: rest.join(":"),
|
|
44677
|
+
origin: origin === "committed" ? "committed" : "uncommitted"
|
|
44678
|
+
},
|
|
44679
|
+
true
|
|
44680
|
+
);
|
|
44681
|
+
}
|
|
44682
|
+
function diffKey(item) {
|
|
44683
|
+
const options = deps.getOptions();
|
|
44684
|
+
return [
|
|
44685
|
+
item?.path || "",
|
|
44686
|
+
options.layout,
|
|
44687
|
+
options.ignoreWs ? "w" : "",
|
|
44688
|
+
options.hideTests ? "t" : "",
|
|
44689
|
+
options.syntax ? "s" : "",
|
|
44690
|
+
fileFilter
|
|
44691
|
+
].join("|");
|
|
44692
|
+
}
|
|
44693
|
+
async function loadShell(item, file, shell) {
|
|
44694
|
+
const seq = lifecycle;
|
|
44695
|
+
const renderKey = diffKey(item);
|
|
44696
|
+
const t2 = text3();
|
|
44697
|
+
const body = shell.querySelector(".gdp-shell-body");
|
|
44698
|
+
if (!body) return;
|
|
44699
|
+
const params = new URLSearchParams({
|
|
44700
|
+
path: item.path,
|
|
44701
|
+
file: file.path,
|
|
44702
|
+
origin: file.origin
|
|
44703
|
+
});
|
|
44704
|
+
if (file.status === "U") params.set("untracked", "1");
|
|
44705
|
+
if (deps.getOptions().ignoreWs) params.set("ignore_ws", "1");
|
|
44706
|
+
try {
|
|
44707
|
+
const res = await deps.trackLoad(
|
|
44708
|
+
fetch(`/_worktree/diff?${params.toString()}`).then(async (response) => {
|
|
44709
|
+
if (!response.ok) {
|
|
44710
|
+
throw new Error(await response.text() || `${response.status}`);
|
|
44711
|
+
}
|
|
44712
|
+
return await response.json();
|
|
44713
|
+
})
|
|
44714
|
+
);
|
|
44715
|
+
if (!isCurrent(seq) || !shell.isConnected || diffKey(item) !== renderKey) {
|
|
44716
|
+
return;
|
|
44717
|
+
}
|
|
44718
|
+
const options = deps.getOptions();
|
|
44719
|
+
const hljs = options.syntax ? await deps.loadHljs() : null;
|
|
44720
|
+
if (!isCurrent(seq) || !shell.isConnected || diffKey(item) !== renderKey) {
|
|
44721
|
+
return;
|
|
44722
|
+
}
|
|
44723
|
+
body.replaceChildren();
|
|
44724
|
+
if (!res.diff.trim()) {
|
|
44725
|
+
body.appendChild(el("div", "gdp-info", t2.panes.diffEmpty));
|
|
44726
|
+
} else {
|
|
44727
|
+
const head = shell.querySelector(".gdp-shell-header");
|
|
44728
|
+
if (head) head.style.display = "none";
|
|
44729
|
+
if (res.truncated) {
|
|
44730
|
+
body.appendChild(
|
|
44731
|
+
el(
|
|
44732
|
+
"div",
|
|
44733
|
+
"gdp-info",
|
|
44734
|
+
t2.panes.diffTruncated(res.renderedHunks, res.totalHunks)
|
|
44735
|
+
)
|
|
44736
|
+
);
|
|
44737
|
+
}
|
|
44738
|
+
const host = el("div", "");
|
|
44739
|
+
body.appendChild(host);
|
|
44740
|
+
const ui = new window.Diff2HtmlUI(
|
|
44741
|
+
host,
|
|
44742
|
+
res.diff,
|
|
44743
|
+
{
|
|
44744
|
+
drawFileList: false,
|
|
44745
|
+
matching: "lines",
|
|
44746
|
+
// topbar の 統合 / 分割。
|
|
44747
|
+
outputFormat: options.layout,
|
|
44748
|
+
synchronisedScroll: true,
|
|
44749
|
+
// topbar の「構文」。diff2html 自身に塗らせる (Diff ビューアは
|
|
44750
|
+
// 巨大ファイル対策で自前の idle 描画を持つが、こちらは 1 本ぶんの
|
|
44751
|
+
// 変更が対象なのでライブラリに任せる)。
|
|
44752
|
+
highlight: !!hljs,
|
|
44753
|
+
fileListToggle: false,
|
|
44754
|
+
fileContentToggle: false
|
|
44755
|
+
},
|
|
44756
|
+
hljs
|
|
44757
|
+
);
|
|
44758
|
+
ui.draw();
|
|
44759
|
+
}
|
|
44760
|
+
shell.classList.add("loaded");
|
|
44761
|
+
} catch (error2) {
|
|
44762
|
+
if (!isCurrent(seq) || !shell.isConnected) return;
|
|
44763
|
+
body.replaceChildren();
|
|
44764
|
+
const failure = el(
|
|
44765
|
+
"div",
|
|
44766
|
+
"gdp-info",
|
|
44767
|
+
error2 instanceof Error ? error2.message : t2.panes.diffFailed
|
|
44768
|
+
);
|
|
44769
|
+
failure.setAttribute("role", "alert");
|
|
44770
|
+
body.appendChild(failure);
|
|
44771
|
+
shell.classList.add("loaded");
|
|
44772
|
+
}
|
|
44773
|
+
}
|
|
44774
|
+
function renderDiffs() {
|
|
44775
|
+
const t2 = text3();
|
|
44776
|
+
const diff = document.getElementById("diff");
|
|
44777
|
+
if (!diff) return;
|
|
44778
|
+
const item = selectedWorktree();
|
|
44779
|
+
observer?.disconnect();
|
|
44780
|
+
observer = null;
|
|
44781
|
+
restoredRouteKey = null;
|
|
44782
|
+
diff.replaceChildren();
|
|
44783
|
+
if (!item) {
|
|
44784
|
+
if (data && data.worktrees.length === 1) {
|
|
44785
|
+
diff.appendChild(introCard());
|
|
44786
|
+
} else {
|
|
44787
|
+
diff.appendChild(el("div", "gdp-info", t2.panes.selectWorktree));
|
|
44788
|
+
}
|
|
44789
|
+
diffFor = "";
|
|
44790
|
+
return;
|
|
44791
|
+
}
|
|
44792
|
+
if (!item.fileCount) {
|
|
44793
|
+
const card = el("div", "gdp-info worktree-empty-diff");
|
|
44794
|
+
card.appendChild(el("p", "", t2.emptyDiff.title));
|
|
44795
|
+
card.appendChild(el("p", "", t2.emptyDiff.body(item.path)));
|
|
44796
|
+
if (!item.missing && !item.bare) {
|
|
44797
|
+
const buttons = el("span", "worktree-empty-diff-actions");
|
|
44798
|
+
const openFolder = openFolderButton(item, true);
|
|
44799
|
+
if (openFolder) buttons.appendChild(openFolder);
|
|
44800
|
+
buttons.appendChild(copyPathButton(item, true));
|
|
44801
|
+
card.appendChild(buttons);
|
|
44802
|
+
}
|
|
44803
|
+
diff.appendChild(card);
|
|
44804
|
+
diffFor = diffKey(item);
|
|
44805
|
+
return;
|
|
44806
|
+
}
|
|
44807
|
+
const files = visibleFiles(item);
|
|
44808
|
+
if (!files.length) {
|
|
44809
|
+
diff.appendChild(el("div", "gdp-info", t2.panes.noFileMatch));
|
|
44810
|
+
diffFor = diffKey(item);
|
|
44811
|
+
return;
|
|
44812
|
+
}
|
|
44813
|
+
const pending = /* @__PURE__ */ new Map();
|
|
44814
|
+
for (const file of files) {
|
|
44815
|
+
const shell = el("div", "gdp-file-shell");
|
|
44816
|
+
shell.dataset.path = file.path;
|
|
44817
|
+
shell.dataset.key = fileKey(file);
|
|
44818
|
+
shell.dataset.status = file.status;
|
|
44819
|
+
const head = el("div", "gdp-shell-header");
|
|
44820
|
+
head.appendChild(el("span", `status-pill ${file.status}`, file.status));
|
|
44821
|
+
head.appendChild(el("span", "path", file.path));
|
|
44822
|
+
const stats = el("span", "stats");
|
|
44823
|
+
stats.appendChild(el("span", "a", `+${file.additions}`));
|
|
44824
|
+
stats.appendChild(el("span", "d", `−${file.deletions}`));
|
|
44825
|
+
head.appendChild(stats);
|
|
44826
|
+
shell.appendChild(head);
|
|
44827
|
+
const body = el("div", "gdp-shell-body");
|
|
44828
|
+
body.appendChild(el("div", "gdp-info", t2.panes.diffLoading));
|
|
44829
|
+
shell.appendChild(body);
|
|
44830
|
+
diff.appendChild(shell);
|
|
44831
|
+
pending.set(shell, file);
|
|
44832
|
+
}
|
|
44833
|
+
diffFor = diffKey(item);
|
|
44834
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
44835
|
+
for (const [shell, file] of pending) void loadShell(item, file, shell);
|
|
44836
|
+
return;
|
|
44837
|
+
}
|
|
44838
|
+
observer = new IntersectionObserver(
|
|
44839
|
+
(entries) => {
|
|
44840
|
+
for (const entry of entries) {
|
|
44841
|
+
if (!entry.isIntersecting) continue;
|
|
44842
|
+
const shell = entry.target;
|
|
44843
|
+
const file = pending.get(shell);
|
|
44844
|
+
if (!file) continue;
|
|
44845
|
+
pending.delete(shell);
|
|
44846
|
+
observer?.unobserve(shell);
|
|
44847
|
+
void loadShell(item, file, shell);
|
|
44848
|
+
}
|
|
44849
|
+
},
|
|
44850
|
+
{ rootMargin: DIFF_PREFETCH_MARGIN }
|
|
44851
|
+
);
|
|
44852
|
+
for (const shell of pending.keys()) observer.observe(shell);
|
|
44853
|
+
}
|
|
44854
|
+
function render() {
|
|
44855
|
+
renderList();
|
|
44856
|
+
renderFiles();
|
|
44857
|
+
const item = selectedWorktree();
|
|
44858
|
+
if (diffKey(item) !== diffFor) renderDiffs();
|
|
44859
|
+
restoreRouteSelection();
|
|
44860
|
+
}
|
|
44861
|
+
function restoreRouteSelection() {
|
|
44862
|
+
const current = route();
|
|
44863
|
+
if (!current?.file || !current.origin) {
|
|
44864
|
+
restoredRouteKey = null;
|
|
44865
|
+
return;
|
|
44866
|
+
}
|
|
44867
|
+
const key = `${current.origin}:${current.file}`;
|
|
44868
|
+
if (key === restoredRouteKey) return;
|
|
44869
|
+
const shell = document.querySelector(
|
|
44870
|
+
`#diff .gdp-file-shell[data-key="${CSS.escape(key)}"]`
|
|
44871
|
+
);
|
|
44872
|
+
if (!shell) return;
|
|
44873
|
+
restoredRouteKey = key;
|
|
44874
|
+
shell.scrollIntoView({ block: "start" });
|
|
44875
|
+
}
|
|
44876
|
+
return {
|
|
44877
|
+
async enter() {
|
|
44878
|
+
if (deps.getRoute().screen !== "worktree") return;
|
|
44879
|
+
if (mounted) {
|
|
44880
|
+
render();
|
|
44881
|
+
return;
|
|
44882
|
+
}
|
|
44883
|
+
mount();
|
|
44884
|
+
await refresh();
|
|
44885
|
+
},
|
|
44886
|
+
suspend,
|
|
44887
|
+
reload() {
|
|
44888
|
+
if (!mounted) return this.enter();
|
|
44889
|
+
return refresh();
|
|
44890
|
+
},
|
|
44891
|
+
displayOptionsChanged() {
|
|
44892
|
+
if (!mounted) return;
|
|
44893
|
+
diffFor = null;
|
|
44894
|
+
render();
|
|
44895
|
+
},
|
|
44896
|
+
handleSse() {
|
|
44897
|
+
if (!mounted) return;
|
|
44898
|
+
if (sseTimer !== null) window.clearTimeout(sseTimer);
|
|
44899
|
+
sseTimer = window.setTimeout(() => {
|
|
44900
|
+
sseTimer = null;
|
|
44901
|
+
void refresh();
|
|
44902
|
+
}, SSE_REFRESH_DELAY_MS);
|
|
44903
|
+
},
|
|
44904
|
+
localize() {
|
|
44905
|
+
if (!mounted) return;
|
|
44906
|
+
diffFor = null;
|
|
44907
|
+
render();
|
|
44908
|
+
}
|
|
44909
|
+
};
|
|
44910
|
+
}
|
|
44911
|
+
|
|
43140
44912
|
// web-src/app.ts
|
|
43141
44913
|
window.GdpExpandLogic = GdpExpandLogic;
|
|
43142
44914
|
(() => {
|
|
@@ -43310,12 +45082,12 @@ ${formatErrorDetail(error2)}`);
|
|
|
43310
45082
|
}
|
|
43311
45083
|
function setProjectBranch(branch) {
|
|
43312
45084
|
PROJECT_BRANCH = branch;
|
|
43313
|
-
const
|
|
43314
|
-
if (!
|
|
43315
|
-
|
|
43316
|
-
const name =
|
|
45085
|
+
const el2 = document.querySelector("#project-branch");
|
|
45086
|
+
if (!el2) return;
|
|
45087
|
+
el2.hidden = !branch;
|
|
45088
|
+
const name = el2.querySelector(".project-branch-name");
|
|
43317
45089
|
if (name) name.textContent = branch;
|
|
43318
|
-
|
|
45090
|
+
el2.title = branch ? `Current branch: ${branch}` : "";
|
|
43319
45091
|
}
|
|
43320
45092
|
function mergeLocalSettings(patch) {
|
|
43321
45093
|
const next = { ...APP_SETTINGS };
|
|
@@ -44209,6 +45981,7 @@ ${error2.stack}` : ""}`
|
|
|
44209
45981
|
history: "History",
|
|
44210
45982
|
journal: "Work Log",
|
|
44211
45983
|
database: "Datastores",
|
|
45984
|
+
worktree: "Worktrees",
|
|
44212
45985
|
tools: "Tools",
|
|
44213
45986
|
help: "Settings & Help"
|
|
44214
45987
|
},
|
|
@@ -44544,6 +46317,7 @@ ${error2.stack}` : ""}`
|
|
|
44544
46317
|
history: "履歴",
|
|
44545
46318
|
journal: "ワークログ",
|
|
44546
46319
|
database: "データストア",
|
|
46320
|
+
worktree: "作業ツリー",
|
|
44547
46321
|
tools: "ツール",
|
|
44548
46322
|
help: "設定・ヘルプ"
|
|
44549
46323
|
},
|
|
@@ -44877,8 +46651,8 @@ ${error2.stack}` : ""}`
|
|
|
44877
46651
|
return UI_TEXT[STATE.language];
|
|
44878
46652
|
}
|
|
44879
46653
|
function setElementText(selector, text3) {
|
|
44880
|
-
const
|
|
44881
|
-
if (
|
|
46654
|
+
const el2 = document.querySelector(selector);
|
|
46655
|
+
if (el2) el2.textContent = text3;
|
|
44882
46656
|
}
|
|
44883
46657
|
function setButtonLabel(button, text3) {
|
|
44884
46658
|
if (button) button.textContent = text3;
|
|
@@ -45064,6 +46838,7 @@ ${error2.stack}` : ""}`
|
|
|
45064
46838
|
});
|
|
45065
46839
|
relocalizeHistory?.();
|
|
45066
46840
|
relocalizeJournal?.();
|
|
46841
|
+
relocalizeWorktree?.();
|
|
45067
46842
|
relocalizeViewerSettings?.();
|
|
45068
46843
|
SOURCE_VIEW.localize();
|
|
45069
46844
|
setElementText(".annotation-panel-head strong", text3.annotations.title);
|
|
@@ -45097,6 +46872,7 @@ ${error2.stack}` : ""}`
|
|
|
45097
46872
|
}
|
|
45098
46873
|
let relocalizeHistory = null;
|
|
45099
46874
|
let relocalizeJournal = null;
|
|
46875
|
+
let relocalizeWorktree = null;
|
|
45100
46876
|
let relocalizeTools = null;
|
|
45101
46877
|
let relocalizeViewerSettings = null;
|
|
45102
46878
|
let relocalizeTerminal = null;
|
|
@@ -45125,14 +46901,14 @@ ${error2.stack}` : ""}`
|
|
|
45125
46901
|
}
|
|
45126
46902
|
}
|
|
45127
46903
|
function setStatus(s2) {
|
|
45128
|
-
const
|
|
45129
|
-
|
|
45130
|
-
if (s2)
|
|
46904
|
+
const el2 = $("#status");
|
|
46905
|
+
el2.classList.remove("live", "refreshing", "error");
|
|
46906
|
+
if (s2) el2.classList.add(s2);
|
|
45131
46907
|
const text3 = uiText();
|
|
45132
46908
|
const label = s2 === "live" ? text3.global.statusLive : s2 === "refreshing" ? text3.global.statusLoading : s2 === "error" ? text3.global.statusError : text3.global.statusIdle;
|
|
45133
|
-
const labelEl =
|
|
46909
|
+
const labelEl = el2.querySelector(".status-label");
|
|
45134
46910
|
if (labelEl) labelEl.textContent = label;
|
|
45135
|
-
|
|
46911
|
+
el2.setAttribute("aria-label", label);
|
|
45136
46912
|
updateNetworkActivity();
|
|
45137
46913
|
}
|
|
45138
46914
|
function applyTheme() {
|
|
@@ -45196,7 +46972,8 @@ ${error2.stack}` : ""}`
|
|
|
45196
46972
|
}
|
|
45197
46973
|
function routeCanUseSyntaxHighlighter(route = STATE.route) {
|
|
45198
46974
|
if (!STATE.syntaxHighlight) return false;
|
|
45199
|
-
if (route.screen === "diff" || route.screen === "history"
|
|
46975
|
+
if (route.screen === "diff" || route.screen === "history" || route.screen === "worktree")
|
|
46976
|
+
return true;
|
|
45200
46977
|
return route.screen === "file" && sourceInternalPathKind(route.path) === null;
|
|
45201
46978
|
}
|
|
45202
46979
|
function ensureSyntaxHighlighterForRoute() {
|
|
@@ -45204,6 +46981,7 @@ ${error2.stack}` : ""}`
|
|
|
45204
46981
|
loadSyntaxHighlighter().then((hljsRef) => {
|
|
45205
46982
|
if (!hljsRef) return;
|
|
45206
46983
|
rerenderLoadedDiffs();
|
|
46984
|
+
WORKTREE_VIEW?.displayOptionsChanged();
|
|
45207
46985
|
});
|
|
45208
46986
|
}
|
|
45209
46987
|
function setLayout(layout, persist = true) {
|
|
@@ -45223,9 +47001,10 @@ ${error2.stack}` : ""}`
|
|
|
45223
47001
|
}
|
|
45224
47002
|
scheduleIdleHighlight(card, file);
|
|
45225
47003
|
});
|
|
47004
|
+
WORKTREE_VIEW?.displayOptionsChanged();
|
|
45226
47005
|
}
|
|
45227
|
-
function setChevronIcon(
|
|
45228
|
-
|
|
47006
|
+
function setChevronIcon(el2) {
|
|
47007
|
+
el2.innerHTML = '<svg class="octicon octicon-chevron-down" viewBox="0 0 12 12" width="12" height="12" fill="currentColor" aria-hidden="true"><path fill="currentColor" d="' + CHEVRON_DOWN_12_PATH + '"></path></svg>';
|
|
45229
47008
|
}
|
|
45230
47009
|
function scopeOmitSourceLabel() {
|
|
45231
47010
|
return savedScopeOmitDirs() != null || savedScopeExcludeNames() != null ? uiText().settings.browserOverride : uiText().settings.serverDefault;
|
|
@@ -45506,6 +47285,7 @@ ${error2.stack}` : ""}`
|
|
|
45506
47285
|
}
|
|
45507
47286
|
let ANNOTATIONS_UI = null;
|
|
45508
47287
|
let JOURNAL_VIEW = null;
|
|
47288
|
+
let WORKTREE_VIEW = null;
|
|
45509
47289
|
function applyInlineAnnotations() {
|
|
45510
47290
|
ANNOTATIONS_UI?.applyInlineAnnotations();
|
|
45511
47291
|
}
|
|
@@ -45608,6 +47388,9 @@ ${error2.stack}` : ""}`
|
|
|
45608
47388
|
if (previousRoute.screen === "journal" && nextRoute.screen !== "journal") {
|
|
45609
47389
|
JOURNAL_VIEW?.suspend();
|
|
45610
47390
|
}
|
|
47391
|
+
if (previousRoute.screen === "worktree" && nextRoute.screen !== "worktree") {
|
|
47392
|
+
WORKTREE_VIEW?.suspend();
|
|
47393
|
+
}
|
|
45611
47394
|
STATE.route = nextRoute;
|
|
45612
47395
|
STATE.from = nextRoute.range.from;
|
|
45613
47396
|
STATE.to = nextRoute.range.to;
|
|
@@ -45634,13 +47417,19 @@ ${error2.stack}` : ""}`
|
|
|
45634
47417
|
removeStandaloneSource();
|
|
45635
47418
|
void JOURNAL_VIEW?.enter();
|
|
45636
47419
|
}
|
|
47420
|
+
if (nextRoute.screen === "worktree") {
|
|
47421
|
+
cancelActiveSourceLoad("navigation");
|
|
47422
|
+
setPageMode();
|
|
47423
|
+
removeStandaloneSource();
|
|
47424
|
+
void WORKTREE_VIEW?.enter();
|
|
47425
|
+
}
|
|
45637
47426
|
}
|
|
45638
|
-
function setQueryHistoryPanelOpen(
|
|
47427
|
+
function setQueryHistoryPanelOpen(open2) {
|
|
45639
47428
|
const panel = document.getElementById("query-history-panel");
|
|
45640
47429
|
if (!panel) return;
|
|
45641
|
-
panel.hidden = !
|
|
45642
|
-
document.body.classList.toggle("query-history-panel-open",
|
|
45643
|
-
if (
|
|
47430
|
+
panel.hidden = !open2;
|
|
47431
|
+
document.body.classList.toggle("query-history-panel-open", open2);
|
|
47432
|
+
if (open2 && ANNOTATIONS_UI) {
|
|
45644
47433
|
ANNOTATIONS_UI.setAnnotationPanelOpen(false);
|
|
45645
47434
|
}
|
|
45646
47435
|
}
|
|
@@ -45679,6 +47468,18 @@ ${error2.stack}` : ""}`
|
|
|
45679
47468
|
"gdp-journal-page",
|
|
45680
47469
|
STATE.route.screen === "journal"
|
|
45681
47470
|
);
|
|
47471
|
+
document.body.classList.toggle(
|
|
47472
|
+
"gdp-worktree-page",
|
|
47473
|
+
STATE.route.screen === "worktree"
|
|
47474
|
+
);
|
|
47475
|
+
document.body.toggleAttribute(
|
|
47476
|
+
"data-content-scrolls-when-docked",
|
|
47477
|
+
STATE.route.screen === "diff" || STATE.route.screen === "history" || STATE.route.screen === "repo" || STATE.route.screen === "file" || STATE.route.screen === "help" || STATE.route.screen === "worktree"
|
|
47478
|
+
);
|
|
47479
|
+
document.body.toggleAttribute(
|
|
47480
|
+
"data-history-list-panel",
|
|
47481
|
+
historyPanelRoute || STATE.route.screen === "worktree"
|
|
47482
|
+
);
|
|
45682
47483
|
const repoTargetWrap = document.querySelector("#repo-target-wrap");
|
|
45683
47484
|
if (!repoSidebarRoute && repoTargetWrap) {
|
|
45684
47485
|
repoTargetWrap.hidden = true;
|
|
@@ -45753,6 +47554,14 @@ ${error2.stack}` : ""}`
|
|
|
45753
47554
|
})
|
|
45754
47555
|
);
|
|
45755
47556
|
}
|
|
47557
|
+
if (link2.dataset.route === "worktree") {
|
|
47558
|
+
link2.href = withOverlayState(
|
|
47559
|
+
buildRoute({
|
|
47560
|
+
screen: "worktree",
|
|
47561
|
+
range: currentRange()
|
|
47562
|
+
})
|
|
47563
|
+
);
|
|
47564
|
+
}
|
|
45756
47565
|
if (link2.dataset.route === "help") {
|
|
45757
47566
|
link2.href = withOverlayState(
|
|
45758
47567
|
buildRoute({
|
|
@@ -45785,7 +47594,9 @@ ${error2.stack}` : ""}`
|
|
|
45785
47594
|
setTimeout(() => {
|
|
45786
47595
|
button?.classList.remove("opened");
|
|
45787
47596
|
}, 1200);
|
|
45788
|
-
|
|
47597
|
+
return true;
|
|
47598
|
+
} catch (error2) {
|
|
47599
|
+
console.error("[code-viewer] failed to open path in OS", error2);
|
|
45789
47600
|
if (button) {
|
|
45790
47601
|
button.classList.add("failed");
|
|
45791
47602
|
button.title = "failed to open in OS";
|
|
@@ -45794,6 +47605,7 @@ ${error2.stack}` : ""}`
|
|
|
45794
47605
|
button.title = oldTitle || "open in OS";
|
|
45795
47606
|
}, 1600);
|
|
45796
47607
|
}
|
|
47608
|
+
return false;
|
|
45797
47609
|
} finally {
|
|
45798
47610
|
if (button) button.disabled = false;
|
|
45799
47611
|
}
|
|
@@ -46316,10 +48128,7 @@ ${error2.stack}` : ""}`
|
|
|
46316
48128
|
moveActiveSidebarItem(e2.key === "ArrowDown" ? 1 : -1);
|
|
46317
48129
|
} else if (e2.key === "Escape") {
|
|
46318
48130
|
if (sbFilter.value) {
|
|
46319
|
-
|
|
46320
|
-
syncSidebarFilterClearButton();
|
|
46321
|
-
flushSidebarFilter();
|
|
46322
|
-
applyFilter();
|
|
48131
|
+
clearSidebarFilter();
|
|
46323
48132
|
} else {
|
|
46324
48133
|
sbFilter.blur();
|
|
46325
48134
|
}
|
|
@@ -46767,6 +48576,9 @@ ${error2.stack}` : ""}`
|
|
|
46767
48576
|
setStatus("live");
|
|
46768
48577
|
return Promise.resolve(null);
|
|
46769
48578
|
}
|
|
48579
|
+
if (STATE.route.screen === "worktree") {
|
|
48580
|
+
return (WORKTREE_VIEW?.reload() ?? Promise.resolve()).then(() => null);
|
|
48581
|
+
}
|
|
46770
48582
|
if (STATE.route.screen === "file" && !(isFileHistoryRoute(STATE.route) && activeHistoryPathFilter) && // load() is by definition a reload (topbar Reload button, ignore-ws
|
|
46771
48583
|
// toggle, catch-up after SSE reconnect) - bypass the idempotent-mount
|
|
46772
48584
|
// guard so the blob view actually refetches, matching the pre-guard
|
|
@@ -46833,6 +48645,8 @@ ${error2.stack}` : ""}`
|
|
|
46833
48645
|
} else if (STATE.route.screen === "journal") {
|
|
46834
48646
|
setStatus("live");
|
|
46835
48647
|
void JOURNAL_VIEW?.enter();
|
|
48648
|
+
} else if (STATE.route.screen === "worktree") {
|
|
48649
|
+
void WORKTREE_VIEW?.enter();
|
|
46836
48650
|
} else load();
|
|
46837
48651
|
syncLineRefPill();
|
|
46838
48652
|
syncDoctorSheetFromUrl();
|
|
@@ -46975,9 +48789,9 @@ ${error2.stack}` : ""}`
|
|
|
46975
48789
|
function isDoctorOverlayOpen() {
|
|
46976
48790
|
return parseDoctorOverlay(window.location.pathname, window.location.search);
|
|
46977
48791
|
}
|
|
46978
|
-
function updateUrlForDoctorOverlay(
|
|
48792
|
+
function updateUrlForDoctorOverlay(open2) {
|
|
46979
48793
|
const current = window.location.pathname + window.location.search;
|
|
46980
|
-
const next = withDoctorOverlay(current,
|
|
48794
|
+
const next = withDoctorOverlay(current, open2);
|
|
46981
48795
|
if (next !== current) {
|
|
46982
48796
|
history.replaceState(history.state, "", next + window.location.hash);
|
|
46983
48797
|
}
|
|
@@ -46996,9 +48810,9 @@ ${error2.stack}` : ""}`
|
|
|
46996
48810
|
}
|
|
46997
48811
|
function syncDoctorSheetFromUrl() {
|
|
46998
48812
|
const shouldOpen = isDoctorOverlayOpen();
|
|
46999
|
-
const
|
|
47000
|
-
if (shouldOpen && !
|
|
47001
|
-
else if (!shouldOpen &&
|
|
48813
|
+
const open2 = DOCTOR_VIEW.isOpen();
|
|
48814
|
+
if (shouldOpen && !open2) void DOCTOR_VIEW.open();
|
|
48815
|
+
else if (!shouldOpen && open2) DOCTOR_VIEW.close();
|
|
47002
48816
|
}
|
|
47003
48817
|
document.getElementById("doctor-sheet-overlay")?.addEventListener("click", () => closeDoctorSheet());
|
|
47004
48818
|
document.addEventListener("keydown", (event) => {
|
|
@@ -47030,10 +48844,10 @@ ${error2.stack}` : ""}`
|
|
|
47030
48844
|
function syncAppPanel() {
|
|
47031
48845
|
const tools = parseToolsOverlay(window.location.search) !== null;
|
|
47032
48846
|
const terminal = parseTerminalOverlay(window.location.search) !== null;
|
|
47033
|
-
const
|
|
48847
|
+
const open2 = tools || terminal;
|
|
47034
48848
|
const panel = document.getElementById("app-panel");
|
|
47035
48849
|
if (panel) {
|
|
47036
|
-
panel.classList.toggle("app-panel-open",
|
|
48850
|
+
panel.classList.toggle("app-panel-open", open2);
|
|
47037
48851
|
}
|
|
47038
48852
|
for (const [id, selected] of [
|
|
47039
48853
|
["#panel-tab-tools", tools],
|
|
@@ -47121,10 +48935,10 @@ ${error2.stack}` : ""}`
|
|
|
47121
48935
|
}
|
|
47122
48936
|
function syncToolsSheetFromUrl() {
|
|
47123
48937
|
const tool = openToolsOverlay();
|
|
47124
|
-
const
|
|
47125
|
-
if (tool && (!
|
|
48938
|
+
const open2 = TOOLS_VIEW.isOpen();
|
|
48939
|
+
if (tool && (!open2 || TOOLS_VIEW.getActiveTool() !== tool))
|
|
47126
48940
|
void TOOLS_VIEW.open(tool);
|
|
47127
|
-
else if (!tool &&
|
|
48941
|
+
else if (!tool && open2) TOOLS_VIEW.close();
|
|
47128
48942
|
syncAppPanel();
|
|
47129
48943
|
}
|
|
47130
48944
|
const TERMINAL_VIEW = createTerminalView({
|
|
@@ -47167,11 +48981,11 @@ ${error2.stack}` : ""}`
|
|
|
47167
48981
|
}
|
|
47168
48982
|
function syncTerminalSheetFromUrl() {
|
|
47169
48983
|
const state = parseTerminalOverlay(window.location.search);
|
|
47170
|
-
const
|
|
48984
|
+
const open2 = TERMINAL_VIEW.isOpen();
|
|
47171
48985
|
const target = state === "open" ? null : state;
|
|
47172
|
-
if (state && (!
|
|
48986
|
+
if (state && (!open2 || target && TERMINAL_VIEW.getActiveTarget() !== target)) {
|
|
47173
48987
|
void TERMINAL_VIEW.open(target);
|
|
47174
|
-
} else if (!state &&
|
|
48988
|
+
} else if (!state && open2) {
|
|
47175
48989
|
TERMINAL_VIEW.close();
|
|
47176
48990
|
}
|
|
47177
48991
|
syncAppPanel();
|
|
@@ -47187,6 +49001,30 @@ ${error2.stack}` : ""}`
|
|
|
47187
49001
|
setStatus
|
|
47188
49002
|
});
|
|
47189
49003
|
relocalizeJournal = () => JOURNAL_VIEW?.localize();
|
|
49004
|
+
WORKTREE_VIEW = createWorktreeView({
|
|
49005
|
+
getRoute: () => STATE.route,
|
|
49006
|
+
// topbar のトグルは Diff ビューアと同じものを使う。値の出所も同じ STATE。
|
|
49007
|
+
getOptions: () => ({
|
|
49008
|
+
layout: STATE.layout,
|
|
49009
|
+
ignoreWs: STATE.ignoreWs,
|
|
49010
|
+
hideTests: STATE.hideTests,
|
|
49011
|
+
syntax: STATE.syntaxHighlight
|
|
49012
|
+
}),
|
|
49013
|
+
isTestPath: isTestFilePath,
|
|
49014
|
+
getSidebarView: () => STATE.sbView,
|
|
49015
|
+
// ハイライタは遅延バンドル。差分を描く直前に読み込ませる。
|
|
49016
|
+
loadHljs: loadSyntaxHighlighter,
|
|
49017
|
+
setRoute,
|
|
49018
|
+
currentRange,
|
|
49019
|
+
trackLoad,
|
|
49020
|
+
getText: () => worktreeText(STATE.language),
|
|
49021
|
+
setPageMode,
|
|
49022
|
+
syncHeaderMenu,
|
|
49023
|
+
setStatus,
|
|
49024
|
+
createOpenPathButton,
|
|
49025
|
+
openPathInOs: (path, kind) => openPathInOs(path, kind)
|
|
49026
|
+
});
|
|
49027
|
+
relocalizeWorktree = () => WORKTREE_VIEW?.localize();
|
|
47190
49028
|
const DATABASE_VIEW = createDatabaseView({
|
|
47191
49029
|
setRoute,
|
|
47192
49030
|
setPageMode,
|
|
@@ -47245,6 +49083,8 @@ ${error2.stack}` : ""}`
|
|
|
47245
49083
|
DATABASE_VIEW.suspend();
|
|
47246
49084
|
if (previousRoute.screen === "journal" && nextRoute.screen !== "journal")
|
|
47247
49085
|
JOURNAL_VIEW?.suspend();
|
|
49086
|
+
if (previousRoute.screen === "worktree" && nextRoute.screen !== "worktree")
|
|
49087
|
+
WORKTREE_VIEW?.suspend();
|
|
47248
49088
|
if (isHistoryPanelRoute(previousRoute) && !isHistoryPanelRoute(nextRoute))
|
|
47249
49089
|
HISTORY_VIEW.leaveHistory();
|
|
47250
49090
|
if (isHistoryPanelRoute(previousRoute) && !isHistoryPanelRoute(nextRoute))
|
|
@@ -47314,6 +49154,13 @@ ${error2.stack}` : ""}`
|
|
|
47314
49154
|
setStatus("live");
|
|
47315
49155
|
return;
|
|
47316
49156
|
}
|
|
49157
|
+
if (STATE.route.screen === "worktree") {
|
|
49158
|
+
cancelActiveSourceLoad("navigation");
|
|
49159
|
+
setPageMode();
|
|
49160
|
+
removeStandaloneSource();
|
|
49161
|
+
void WORKTREE_VIEW?.enter();
|
|
49162
|
+
return;
|
|
49163
|
+
}
|
|
47317
49164
|
if (STATE.route.screen !== "file") {
|
|
47318
49165
|
cancelActiveSourceLoad("navigation");
|
|
47319
49166
|
setPageMode();
|
|
@@ -47365,6 +49212,7 @@ ${error2.stack}` : ""}`
|
|
|
47365
49212
|
ensureSyntaxHighlighterForRoute();
|
|
47366
49213
|
} else {
|
|
47367
49214
|
rerenderLoadedDiffs();
|
|
49215
|
+
WORKTREE_VIEW?.displayOptionsChanged();
|
|
47368
49216
|
}
|
|
47369
49217
|
}
|
|
47370
49218
|
setHighlightButton(STATE.syntaxHighlight && getHljs() ? "loaded" : "idle");
|
|
@@ -47389,6 +49237,7 @@ ${error2.stack}` : ""}`
|
|
|
47389
49237
|
else updateTreeDirVisibility();
|
|
47390
49238
|
if (typeof applyViewedState === "function") applyViewedState();
|
|
47391
49239
|
applyHideTestsToMeta();
|
|
49240
|
+
WORKTREE_VIEW?.displayOptionsChanged();
|
|
47392
49241
|
}
|
|
47393
49242
|
function visibleDiffMetaForBrief(meta) {
|
|
47394
49243
|
if (!meta.totals) return meta;
|
|
@@ -47441,7 +49290,7 @@ ${error2.stack}` : ""}`
|
|
|
47441
49290
|
getFiles: () => STATE.files,
|
|
47442
49291
|
getRoute: () => STATE.route,
|
|
47443
49292
|
getAnnotationPanelOpen: () => APP_SETTINGS.annotationPanelOpen === true,
|
|
47444
|
-
setAnnotationPanelOpenState: (
|
|
49293
|
+
setAnnotationPanelOpenState: (open2) => patchSettings({ annotationPanelOpen: open2 }),
|
|
47445
49294
|
getAnnotationPanelWidth: () => APP_SETTINGS.annotationPanelWidth,
|
|
47446
49295
|
setAnnotationPanelWidth: (width) => patchSettings({ annotationPanelWidth: width }),
|
|
47447
49296
|
getAnnotationFollow: () => APP_SETTINGS.annotationFollow !== false,
|
|
@@ -47502,7 +49351,7 @@ ${error2.stack}` : ""}`
|
|
|
47502
49351
|
$,
|
|
47503
49352
|
getActiveSessionEntries: () => ANNOTATIONS_UI?.getActiveSessionEntries() ?? [],
|
|
47504
49353
|
openAnnotationEntry: (id) => ANNOTATIONS_UI ? ANNOTATIONS_UI.openAnnotationEntry(id) : Promise.resolve(),
|
|
47505
|
-
setAnnotationPanelOpen: (
|
|
49354
|
+
setAnnotationPanelOpen: (open2) => ANNOTATIONS_UI?.setAnnotationPanelOpen(open2),
|
|
47506
49355
|
onAnnotationsChanged: (cb) => ANNOTATIONS_UI?.onAnnotationsChanged(cb),
|
|
47507
49356
|
onAnnotationOpened: (cb) => ANNOTATIONS_UI?.onAnnotationOpened(cb),
|
|
47508
49357
|
getActiveAnnotationId: () => ANNOTATIONS_UI ? ANNOTATIONS_UI.getActiveAnnotationId() : null,
|
|
@@ -47745,6 +49594,7 @@ ${error2.stack}` : ""}`
|
|
|
47745
49594
|
}
|
|
47746
49595
|
}
|
|
47747
49596
|
if (isHistoryPanelRoute(STATE.route)) HISTORY_VIEW.notePossibleUpdate();
|
|
49597
|
+
if (STATE.route.screen === "worktree") WORKTREE_VIEW?.handleSse();
|
|
47748
49598
|
scheduleSseLoad(paths);
|
|
47749
49599
|
});
|
|
47750
49600
|
es.addEventListener("watch-limit", (event) => {
|