@youtyan/code-viewer 0.8.5 → 0.8.6
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 +10 -8
- package/dist/code-viewer.js +160 -754
- package/package.json +1 -1
- package/web/app.js +66 -20
package/package.json
CHANGED
package/web/app.js
CHANGED
|
@@ -9672,6 +9672,10 @@ ${frontmatter.yaml}
|
|
|
9672
9672
|
}
|
|
9673
9673
|
|
|
9674
9674
|
// web-src/views/file-shell.ts
|
|
9675
|
+
function isMediaPreviewOnlySource(path) {
|
|
9676
|
+
const kind = sourceDisplayKind(path);
|
|
9677
|
+
return kind === "image" || kind === "video" || kind === "audio" || kind === "pdf";
|
|
9678
|
+
}
|
|
9675
9679
|
function isBlobOrBlameFileRoute(route) {
|
|
9676
9680
|
return route.screen === "file" && (route.view === "blob" || route.view === "blame");
|
|
9677
9681
|
}
|
|
@@ -9724,14 +9728,18 @@ ${frontmatter.yaml}
|
|
|
9724
9728
|
}
|
|
9725
9729
|
function appendFileViewTabs(tabs, deps, target, activeTab, options = {}) {
|
|
9726
9730
|
const includeFileTabs = options.includeFileTabs !== false;
|
|
9727
|
-
const
|
|
9731
|
+
const mediaOnly = options.previewable === undefined && isMediaPreviewOnlySource(target.path);
|
|
9732
|
+
const showPreview = mediaOnly || (options.previewable ?? (isPreviewableSource(target.path) || activeTab === "preview"));
|
|
9728
9733
|
let previewButton = null;
|
|
9729
9734
|
if (showPreview) {
|
|
9730
|
-
previewButton = createBlobSourceTabButton(deps, target, "preview", activeTab === "preview", options);
|
|
9735
|
+
previewButton = createBlobSourceTabButton(deps, target, "preview", activeTab === "preview" || mediaOnly && activeTab === "code", options);
|
|
9731
9736
|
tabs.appendChild(previewButton);
|
|
9732
9737
|
}
|
|
9733
|
-
|
|
9734
|
-
|
|
9738
|
+
let codeButton = null;
|
|
9739
|
+
if (!mediaOnly) {
|
|
9740
|
+
codeButton = createBlobSourceTabButton(deps, target, "code", activeTab === "code", options);
|
|
9741
|
+
tabs.appendChild(codeButton);
|
|
9742
|
+
}
|
|
9735
9743
|
if (includeFileTabs) {
|
|
9736
9744
|
tabs.appendChild(createFileViewTabButton(deps, target, "blame", "Blame", activeTab === "blame"));
|
|
9737
9745
|
tabs.appendChild(createFileViewTabButton(deps, target, "history", "History", activeTab === "history"));
|
|
@@ -26044,7 +26052,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26044
26052
|
},
|
|
26045
26053
|
{
|
|
26046
26054
|
kind: "paragraph",
|
|
26047
|
-
text: "A file detail page exposes four tabs — Preview, Code, Blame, History. Code is the default and ?preview=1 opts in to the Markdown / media
|
|
26055
|
+
text: "A file detail page exposes up to four tabs — Preview, Code, Blame, History. For text files Code is the default and ?preview=1 opts in to the Markdown / HTML preview; media files (images, video, audio, PDF) show a Preview tab only, with no Code tab. Blame and History have their own canonical URLs (view=blame, view=history) so deep links and the browser back/forward stay in sync, and they keep the Repository sidebar visible."
|
|
26048
26056
|
},
|
|
26049
26057
|
{
|
|
26050
26058
|
kind: "paragraph",
|
|
@@ -26715,7 +26723,7 @@ code-viewer query agent-help`
|
|
|
26715
26723
|
},
|
|
26716
26724
|
{
|
|
26717
26725
|
kind: "paragraph",
|
|
26718
|
-
text: "
|
|
26726
|
+
text: "ファイル詳細ページには最大 4 つのタブ (Preview / Code / Blame / History) があります。テキストファイルは Code がデフォルトで、?preview=1 を付けると Markdown / HTML プレビューに切り替わります。画像・動画・音声・PDF などのメディアファイルは Preview タブのみ表示され、Code タブは表示されません。Blame と History はそれぞれ専用 URL (view=blame, view=history) を持つため、ディープリンクとブラウザの戻る / 進むが同期し、いずれも Repository サイドバーは表示されたままです。"
|
|
26719
26727
|
},
|
|
26720
26728
|
{
|
|
26721
26729
|
kind: "paragraph",
|
|
@@ -34083,6 +34091,8 @@ code-viewer query agent-help`
|
|
|
34083
34091
|
});
|
|
34084
34092
|
}
|
|
34085
34093
|
function applyRenderedSourceTab(tab, codeButton, previewButton, codePane, previewPane, updateRoute = true) {
|
|
34094
|
+
if (!codeButton)
|
|
34095
|
+
return false;
|
|
34086
34096
|
if (tab === "preview" && (!previewButton || !previewPane))
|
|
34087
34097
|
return false;
|
|
34088
34098
|
codeButton.classList.toggle("active", tab === "code");
|
|
@@ -34332,6 +34342,7 @@ code-viewer query agent-help`
|
|
|
34332
34342
|
body.replaceWith(view);
|
|
34333
34343
|
else
|
|
34334
34344
|
card.appendChild(view);
|
|
34345
|
+
setSourceCardState(card, "error");
|
|
34335
34346
|
}
|
|
34336
34347
|
function renderSourceCancelled(card, target) {
|
|
34337
34348
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
@@ -34356,6 +34367,7 @@ code-viewer query agent-help`
|
|
|
34356
34367
|
body.replaceWith(view);
|
|
34357
34368
|
else
|
|
34358
34369
|
card.appendChild(view);
|
|
34370
|
+
setSourceCardState(card, "cancelled");
|
|
34359
34371
|
}
|
|
34360
34372
|
function renderSourceUnsupported(card, target) {
|
|
34361
34373
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
@@ -34374,6 +34386,7 @@ code-viewer query agent-help`
|
|
|
34374
34386
|
body.replaceWith(view);
|
|
34375
34387
|
else
|
|
34376
34388
|
card.appendChild(view);
|
|
34389
|
+
setSourceCardState(card, "done");
|
|
34377
34390
|
}
|
|
34378
34391
|
function renderSourceInternalPath(card, target, kind) {
|
|
34379
34392
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
@@ -34398,6 +34411,7 @@ code-viewer query agent-help`
|
|
|
34398
34411
|
body.replaceWith(view);
|
|
34399
34412
|
else
|
|
34400
34413
|
card.appendChild(view);
|
|
34414
|
+
setSourceCardState(card, "done");
|
|
34401
34415
|
}
|
|
34402
34416
|
function renderHtmlPreview(target, html) {
|
|
34403
34417
|
return renderHtmlPreviewFrame(`${target.path} preview`, html);
|
|
@@ -34511,7 +34525,7 @@ code-viewer query agent-help`
|
|
|
34511
34525
|
previewButton2?.addEventListener("click", () => {
|
|
34512
34526
|
applyRenderedSourceTab("preview", codeButton2, previewButton2, virtualCode, preview);
|
|
34513
34527
|
});
|
|
34514
|
-
codeButton2
|
|
34528
|
+
codeButton2?.addEventListener("click", () => {
|
|
34515
34529
|
applyRenderedSourceTab("code", codeButton2, previewButton2, virtualCode, preview);
|
|
34516
34530
|
});
|
|
34517
34531
|
if (header)
|
|
@@ -34606,7 +34620,7 @@ code-viewer query agent-help`
|
|
|
34606
34620
|
previewButton?.addEventListener("click", () => {
|
|
34607
34621
|
applyRenderedSourceTab("preview", codeButton, previewButton, table2, preview);
|
|
34608
34622
|
});
|
|
34609
|
-
codeButton
|
|
34623
|
+
codeButton?.addEventListener("click", () => {
|
|
34610
34624
|
applyRenderedSourceTab("code", codeButton, previewButton, table2, preview);
|
|
34611
34625
|
});
|
|
34612
34626
|
if (header)
|
|
@@ -34926,7 +34940,7 @@ code-viewer query agent-help`
|
|
|
34926
34940
|
e2.preventDefault();
|
|
34927
34941
|
const url = new URL(full.href, window.location.origin);
|
|
34928
34942
|
setRoute(parseRoute(url.pathname, url.search, currentRange()), true);
|
|
34929
|
-
renderStandaloneSource(target);
|
|
34943
|
+
renderStandaloneSource(target, { refresh: true });
|
|
34930
34944
|
});
|
|
34931
34945
|
actions.append(copy, full);
|
|
34932
34946
|
info.append(badge, summary, actions);
|
|
@@ -35042,7 +35056,7 @@ code-viewer query agent-help`
|
|
|
35042
35056
|
e2.preventDefault();
|
|
35043
35057
|
const url = new URL(full.href, window.location.origin);
|
|
35044
35058
|
setRoute(parseRoute(url.pathname, url.search, currentRange()), true);
|
|
35045
|
-
renderStandaloneSource(target);
|
|
35059
|
+
renderStandaloneSource(target, { refresh: true });
|
|
35046
35060
|
});
|
|
35047
35061
|
actions.append(raw, full);
|
|
35048
35062
|
info.append(badge, summary, actions);
|
|
@@ -35308,6 +35322,7 @@ code-viewer query agent-help`
|
|
|
35308
35322
|
body.replaceWith(view);
|
|
35309
35323
|
else
|
|
35310
35324
|
card.appendChild(view);
|
|
35325
|
+
setSourceCardState(card, "done");
|
|
35311
35326
|
}
|
|
35312
35327
|
function _renderSourceBinary(card, target) {
|
|
35313
35328
|
const body = card.querySelector(".gdp-file-detail-body, .d2h-files-diff, .d2h-file-diff, .gdp-media, .gdp-source-viewer");
|
|
@@ -35331,7 +35346,30 @@ code-viewer query agent-help`
|
|
|
35331
35346
|
else
|
|
35332
35347
|
card.appendChild(view);
|
|
35333
35348
|
}
|
|
35334
|
-
|
|
35349
|
+
function mountedStandaloneSourceCard(target) {
|
|
35350
|
+
const card = document.querySelector(".gdp-standalone-source");
|
|
35351
|
+
if (!card)
|
|
35352
|
+
return null;
|
|
35353
|
+
if (card.dataset.path !== target.path)
|
|
35354
|
+
return null;
|
|
35355
|
+
if (card.dataset.sourceRef !== (target.ref || "worktree"))
|
|
35356
|
+
return null;
|
|
35357
|
+
return card;
|
|
35358
|
+
}
|
|
35359
|
+
function setSourceCardState(card, state) {
|
|
35360
|
+
card.dataset.sourceState = state;
|
|
35361
|
+
}
|
|
35362
|
+
async function renderStandaloneSource(target, options = {}) {
|
|
35363
|
+
if (!options.refresh) {
|
|
35364
|
+
const mounted = mountedStandaloneSourceCard(target);
|
|
35365
|
+
const state = mounted?.dataset.sourceState;
|
|
35366
|
+
if (mounted && state === "done") {
|
|
35367
|
+
scrollStandaloneSourceLine(mounted, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35368
|
+
return;
|
|
35369
|
+
}
|
|
35370
|
+
if (mounted && state === "loading")
|
|
35371
|
+
return;
|
|
35372
|
+
}
|
|
35335
35373
|
cancelActiveSourceLoad("navigation");
|
|
35336
35374
|
const req = ++SOURCE_REQ_SEQ;
|
|
35337
35375
|
const repoTarget = repoFileTargetFromRoute();
|
|
@@ -35343,10 +35381,13 @@ code-viewer query agent-help`
|
|
|
35343
35381
|
const card = document.createElement("article");
|
|
35344
35382
|
card.className = "gdp-file-shell loaded gdp-standalone-source gdp-source-mode";
|
|
35345
35383
|
card.dataset.path = target.path;
|
|
35384
|
+
card.dataset.sourceRef = target.ref || "worktree";
|
|
35385
|
+
setSourceCardState(card, "loading");
|
|
35346
35386
|
const internalKind = sourceInternalPathKind(target.path);
|
|
35347
35387
|
const wrapper = document.createElement("div");
|
|
35348
35388
|
wrapper.className = "gdp-file-detail-wrapper";
|
|
35349
|
-
const
|
|
35389
|
+
const mediaOnly = !internalKind && isMediaPreviewOnlySource(target.path);
|
|
35390
|
+
const activeTab = mediaOnly || !internalKind && STATE.route.screen === "file" && STATE.route.preview ? "preview" : "code";
|
|
35350
35391
|
const { sticky, header } = createFileShellSticky({
|
|
35351
35392
|
currentRange,
|
|
35352
35393
|
setRoute,
|
|
@@ -35427,9 +35468,13 @@ code-viewer query agent-help`
|
|
|
35427
35468
|
const rendered2 = await renderPagedSourceText(card, target, meta.size, controller.signal);
|
|
35428
35469
|
if (req !== SOURCE_REQ_SEQ || !sourceTargetsEqual(sourceTargetFromRoute(), target))
|
|
35429
35470
|
return;
|
|
35430
|
-
if (!rendered2)
|
|
35471
|
+
if (!rendered2) {
|
|
35472
|
+
finishSourceLoad(req);
|
|
35473
|
+
renderSourceError(card, target, `Cannot load ${target.path} at ${target.ref}`);
|
|
35431
35474
|
return;
|
|
35475
|
+
}
|
|
35432
35476
|
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35477
|
+
setSourceCardState(card, "done");
|
|
35433
35478
|
finishSourceLoad(req);
|
|
35434
35479
|
return;
|
|
35435
35480
|
}
|
|
@@ -35450,6 +35495,7 @@ code-viewer query agent-help`
|
|
|
35450
35495
|
if (!rendered)
|
|
35451
35496
|
return;
|
|
35452
35497
|
scrollStandaloneSourceLine(card, lineTargetStart(STATE.route.screen === "file" ? STATE.route.line : undefined));
|
|
35498
|
+
setSourceCardState(card, "done");
|
|
35453
35499
|
finishSourceLoad(req);
|
|
35454
35500
|
}
|
|
35455
35501
|
} catch (err) {
|
|
@@ -35477,7 +35523,7 @@ code-viewer query agent-help`
|
|
|
35477
35523
|
if (row)
|
|
35478
35524
|
row.scrollIntoView({ block: "center" });
|
|
35479
35525
|
}
|
|
35480
|
-
function applySourceRouteToShell() {
|
|
35526
|
+
function applySourceRouteToShell(options = {}) {
|
|
35481
35527
|
const target = sourceTargetFromRoute();
|
|
35482
35528
|
setPageMode();
|
|
35483
35529
|
if (!target) {
|
|
@@ -35487,7 +35533,7 @@ code-viewer query agent-help`
|
|
|
35487
35533
|
});
|
|
35488
35534
|
return;
|
|
35489
35535
|
}
|
|
35490
|
-
renderStandaloneSource(target);
|
|
35536
|
+
renderStandaloneSource(target, options);
|
|
35491
35537
|
}
|
|
35492
35538
|
function inferLang(path) {
|
|
35493
35539
|
const name = sourceFileName(path);
|
|
@@ -37636,12 +37682,12 @@ code-viewer query agent-help`
|
|
|
37636
37682
|
history.replaceState(historyStateForRoute(STATE.route), "", url + window.location.hash);
|
|
37637
37683
|
}
|
|
37638
37684
|
}
|
|
37639
|
-
function dispatchFileRoute(route) {
|
|
37685
|
+
function dispatchFileRoute(route, options = {}) {
|
|
37640
37686
|
if (route.view === "blob") {
|
|
37641
37687
|
setStatus("live");
|
|
37642
37688
|
removeFileHistoryShell2();
|
|
37643
37689
|
BLAME_VIEW.removeBlamePage();
|
|
37644
|
-
applySourceRouteToShell();
|
|
37690
|
+
applySourceRouteToShell(options);
|
|
37645
37691
|
return true;
|
|
37646
37692
|
}
|
|
37647
37693
|
if (route.view === "blame") {
|
|
@@ -38649,7 +38695,7 @@ code-viewer query agent-help`
|
|
|
38649
38695
|
setStatus("live");
|
|
38650
38696
|
return Promise.resolve(null);
|
|
38651
38697
|
}
|
|
38652
|
-
if (STATE.route.screen === "file" && !(isFileHistoryRoute(STATE.route) && activeHistoryPathFilter) && dispatchFileRoute(STATE.route)) {
|
|
38698
|
+
if (STATE.route.screen === "file" && !(isFileHistoryRoute(STATE.route) && activeHistoryPathFilter) && dispatchFileRoute(STATE.route, { refresh: true })) {
|
|
38653
38699
|
return Promise.resolve({
|
|
38654
38700
|
structureChanged: false,
|
|
38655
38701
|
invalidatedCards: 0,
|
|
@@ -39342,7 +39388,7 @@ code-viewer query agent-help`
|
|
|
39342
39388
|
if (!shouldAutoLoadCurrentRoute(route))
|
|
39343
39389
|
return;
|
|
39344
39390
|
if (isBlobOrBlameFileRoute(route)) {
|
|
39345
|
-
dispatchFileRoute(route);
|
|
39391
|
+
dispatchFileRoute(route, { refresh: true });
|
|
39346
39392
|
return;
|
|
39347
39393
|
}
|
|
39348
39394
|
doSseLoad(paths);
|
|
@@ -39382,7 +39428,7 @@ code-viewer query agent-help`
|
|
|
39382
39428
|
const viewingPath = route.path;
|
|
39383
39429
|
if (paths && viewingPath && !paths.has(viewingPath))
|
|
39384
39430
|
return;
|
|
39385
|
-
dispatchFileRoute(route);
|
|
39431
|
+
dispatchFileRoute(route, { refresh: true });
|
|
39386
39432
|
return;
|
|
39387
39433
|
}
|
|
39388
39434
|
if (route.screen === "repo") {
|