@youtyan/code-viewer 0.11.0 → 0.11.2
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 +5 -0
- package/dist/code-viewer.js +567 -283
- package/package.json +3 -1
- package/web/app.js +483 -40
- package/web/style.css +237 -0
package/web/app.js
CHANGED
|
@@ -1818,7 +1818,7 @@ ${lines.join("\n")}
|
|
|
1818
1818
|
return SOURCE_SHIKI_LANG_ALIASES[lang] || lang;
|
|
1819
1819
|
}
|
|
1820
1820
|
function isPreviewableSource(path) {
|
|
1821
|
-
return /\.(md|markdown|mdown|mkdn|mdx|html|htm)$/i.test(path);
|
|
1821
|
+
return /\.(md|markdown|mdown|mkdn|mdx|html|htm|csv|tsv)$/i.test(path);
|
|
1822
1822
|
}
|
|
1823
1823
|
function sourceInternalPathKind(path) {
|
|
1824
1824
|
for (const part of path.split(/[\\/]+/)) {
|
|
@@ -1831,6 +1831,8 @@ ${lines.join("\n")}
|
|
|
1831
1831
|
function sourcePreviewKind(path) {
|
|
1832
1832
|
if (/\.(md|markdown|mdown|mkdn|mdx)$/i.test(path)) return "markdown";
|
|
1833
1833
|
if (/\.(html|htm)$/i.test(path)) return "html";
|
|
1834
|
+
if (/\.csv$/i.test(path)) return "csv";
|
|
1835
|
+
if (/\.tsv$/i.test(path)) return "tsv";
|
|
1834
1836
|
return null;
|
|
1835
1837
|
}
|
|
1836
1838
|
var EXT_TO_LANG = {
|
|
@@ -8379,6 +8381,22 @@ ${lines.join("\n")}
|
|
|
8379
8381
|
md.core.ruler.after("inline", "footnote_tail", footnote_tail);
|
|
8380
8382
|
}
|
|
8381
8383
|
|
|
8384
|
+
// web-src/core/lazy-bundle.ts
|
|
8385
|
+
function createBundleLoader(bundleFile, init) {
|
|
8386
|
+
let pending = null;
|
|
8387
|
+
return () => {
|
|
8388
|
+
if (!pending) {
|
|
8389
|
+
pending = import(
|
|
8390
|
+
/* @vite-ignore */
|
|
8391
|
+
`/${bundleFile}`
|
|
8392
|
+
).then(
|
|
8393
|
+
(mod) => init ? init(mod) : mod
|
|
8394
|
+
);
|
|
8395
|
+
}
|
|
8396
|
+
return pending;
|
|
8397
|
+
};
|
|
8398
|
+
}
|
|
8399
|
+
|
|
8382
8400
|
// web-src/core/mermaid-loader.ts
|
|
8383
8401
|
var DEFAULT_CONFIG = {
|
|
8384
8402
|
startOnLoad: false,
|
|
@@ -8386,18 +8404,19 @@ ${lines.join("\n")}
|
|
|
8386
8404
|
theme: "default",
|
|
8387
8405
|
er: { useMaxWidth: false }
|
|
8388
8406
|
};
|
|
8407
|
+
var loadMermaidModule = createBundleLoader("mermaid.js");
|
|
8389
8408
|
var mermaidPromise = null;
|
|
8390
8409
|
var initialized = false;
|
|
8391
8410
|
function loadMermaid() {
|
|
8392
8411
|
if (!mermaidPromise) {
|
|
8393
|
-
mermaidPromise =
|
|
8412
|
+
mermaidPromise = loadMermaidModule().then((mod) => {
|
|
8394
8413
|
const mermaid = mod.default;
|
|
8395
8414
|
if (!initialized) {
|
|
8396
8415
|
mermaid.initialize(DEFAULT_CONFIG);
|
|
8397
8416
|
initialized = true;
|
|
8398
8417
|
}
|
|
8399
8418
|
return mermaid;
|
|
8400
|
-
})
|
|
8419
|
+
});
|
|
8401
8420
|
}
|
|
8402
8421
|
return mermaidPromise;
|
|
8403
8422
|
}
|
|
@@ -8415,6 +8434,7 @@ ${lines.join("\n")}
|
|
|
8415
8434
|
const pre = template.content.querySelector("pre");
|
|
8416
8435
|
return pre ? pre.innerHTML : "";
|
|
8417
8436
|
}
|
|
8437
|
+
var loadShikiModule = createBundleLoader("shiki.js");
|
|
8418
8438
|
var cache = /* @__PURE__ */ new Map();
|
|
8419
8439
|
function loadShikiHighlighter(options) {
|
|
8420
8440
|
const key = JSON.stringify({
|
|
@@ -8423,12 +8443,12 @@ ${lines.join("\n")}
|
|
|
8423
8443
|
});
|
|
8424
8444
|
const cached = cache.get(key);
|
|
8425
8445
|
if (cached) return cached;
|
|
8426
|
-
const promise =
|
|
8446
|
+
const promise = loadShikiModule().then(
|
|
8427
8447
|
(mod) => mod.createHighlighter({
|
|
8428
8448
|
themes: options.themes,
|
|
8429
8449
|
langs: options.langs
|
|
8430
8450
|
})
|
|
8431
|
-
)
|
|
8451
|
+
);
|
|
8432
8452
|
cache.set(key, promise);
|
|
8433
8453
|
return promise;
|
|
8434
8454
|
}
|
|
@@ -15642,8 +15662,8 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
15642
15662
|
function formatTime(iso) {
|
|
15643
15663
|
try {
|
|
15644
15664
|
const d2 = new Date(iso);
|
|
15645
|
-
const
|
|
15646
|
-
return `${d2.getFullYear()}-${
|
|
15665
|
+
const pad2 = (n2) => String(n2).padStart(2, "0");
|
|
15666
|
+
return `${d2.getFullYear()}-${pad2(d2.getMonth() + 1)}-${pad2(d2.getDate())} ${pad2(d2.getHours())}:${pad2(d2.getMinutes())}:${pad2(d2.getSeconds())}`;
|
|
15647
15667
|
} catch {
|
|
15648
15668
|
return iso;
|
|
15649
15669
|
}
|
|
@@ -16376,7 +16396,419 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
16376
16396
|
return idx >= 0 ? trimmed.slice(idx + 1) : trimmed;
|
|
16377
16397
|
}
|
|
16378
16398
|
|
|
16399
|
+
// node_modules/.pnpm/d3-dsv@3.0.1/node_modules/d3-dsv/src/dsv.js
|
|
16400
|
+
var EOL = {};
|
|
16401
|
+
var EOF = {};
|
|
16402
|
+
var QUOTE = 34;
|
|
16403
|
+
var NEWLINE = 10;
|
|
16404
|
+
var RETURN = 13;
|
|
16405
|
+
function objectConverter(columns) {
|
|
16406
|
+
return new Function("d", "return {" + columns.map(function(name, i2) {
|
|
16407
|
+
return JSON.stringify(name) + ": d[" + i2 + '] || ""';
|
|
16408
|
+
}).join(",") + "}");
|
|
16409
|
+
}
|
|
16410
|
+
function customConverter(columns, f2) {
|
|
16411
|
+
var object = objectConverter(columns);
|
|
16412
|
+
return function(row, i2) {
|
|
16413
|
+
return f2(object(row), i2, columns);
|
|
16414
|
+
};
|
|
16415
|
+
}
|
|
16416
|
+
function inferColumns(rows) {
|
|
16417
|
+
var columnSet = /* @__PURE__ */ Object.create(null), columns = [];
|
|
16418
|
+
rows.forEach(function(row) {
|
|
16419
|
+
for (var column in row) {
|
|
16420
|
+
if (!(column in columnSet)) {
|
|
16421
|
+
columns.push(columnSet[column] = column);
|
|
16422
|
+
}
|
|
16423
|
+
}
|
|
16424
|
+
});
|
|
16425
|
+
return columns;
|
|
16426
|
+
}
|
|
16427
|
+
function pad(value, width) {
|
|
16428
|
+
var s2 = value + "", length = s2.length;
|
|
16429
|
+
return length < width ? new Array(width - length + 1).join(0) + s2 : s2;
|
|
16430
|
+
}
|
|
16431
|
+
function formatYear(year) {
|
|
16432
|
+
return year < 0 ? "-" + pad(-year, 6) : year > 9999 ? "+" + pad(year, 6) : pad(year, 4);
|
|
16433
|
+
}
|
|
16434
|
+
function formatDate(date) {
|
|
16435
|
+
var hours = date.getUTCHours(), minutes = date.getUTCMinutes(), seconds = date.getUTCSeconds(), milliseconds = date.getUTCMilliseconds();
|
|
16436
|
+
return isNaN(date) ? "Invalid Date" : formatYear(date.getUTCFullYear(), 4) + "-" + pad(date.getUTCMonth() + 1, 2) + "-" + pad(date.getUTCDate(), 2) + (milliseconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2) + "." + pad(milliseconds, 3) + "Z" : seconds ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2) + "Z" : minutes || hours ? "T" + pad(hours, 2) + ":" + pad(minutes, 2) + "Z" : "");
|
|
16437
|
+
}
|
|
16438
|
+
function dsv_default(delimiter2) {
|
|
16439
|
+
var reFormat = new RegExp('["' + delimiter2 + "\n\r]"), DELIMITER = delimiter2.charCodeAt(0);
|
|
16440
|
+
function parse(text3, f2) {
|
|
16441
|
+
var convert, columns, rows = parseRows(text3, function(row, i2) {
|
|
16442
|
+
if (convert) return convert(row, i2 - 1);
|
|
16443
|
+
columns = row, convert = f2 ? customConverter(row, f2) : objectConverter(row);
|
|
16444
|
+
});
|
|
16445
|
+
rows.columns = columns || [];
|
|
16446
|
+
return rows;
|
|
16447
|
+
}
|
|
16448
|
+
function parseRows(text3, f2) {
|
|
16449
|
+
var rows = [], N = text3.length, I = 0, n2 = 0, t2, eof = N <= 0, eol = false;
|
|
16450
|
+
if (text3.charCodeAt(N - 1) === NEWLINE) --N;
|
|
16451
|
+
if (text3.charCodeAt(N - 1) === RETURN) --N;
|
|
16452
|
+
function token() {
|
|
16453
|
+
if (eof) return EOF;
|
|
16454
|
+
if (eol) return eol = false, EOL;
|
|
16455
|
+
var i2, j = I, c2;
|
|
16456
|
+
if (text3.charCodeAt(j) === QUOTE) {
|
|
16457
|
+
while (I++ < N && text3.charCodeAt(I) !== QUOTE || text3.charCodeAt(++I) === QUOTE) ;
|
|
16458
|
+
if ((i2 = I) >= N) eof = true;
|
|
16459
|
+
else if ((c2 = text3.charCodeAt(I++)) === NEWLINE) eol = true;
|
|
16460
|
+
else if (c2 === RETURN) {
|
|
16461
|
+
eol = true;
|
|
16462
|
+
if (text3.charCodeAt(I) === NEWLINE) ++I;
|
|
16463
|
+
}
|
|
16464
|
+
return text3.slice(j + 1, i2 - 1).replace(/""/g, '"');
|
|
16465
|
+
}
|
|
16466
|
+
while (I < N) {
|
|
16467
|
+
if ((c2 = text3.charCodeAt(i2 = I++)) === NEWLINE) eol = true;
|
|
16468
|
+
else if (c2 === RETURN) {
|
|
16469
|
+
eol = true;
|
|
16470
|
+
if (text3.charCodeAt(I) === NEWLINE) ++I;
|
|
16471
|
+
} else if (c2 !== DELIMITER) continue;
|
|
16472
|
+
return text3.slice(j, i2);
|
|
16473
|
+
}
|
|
16474
|
+
return eof = true, text3.slice(j, N);
|
|
16475
|
+
}
|
|
16476
|
+
while ((t2 = token()) !== EOF) {
|
|
16477
|
+
var row = [];
|
|
16478
|
+
while (t2 !== EOL && t2 !== EOF) row.push(t2), t2 = token();
|
|
16479
|
+
if (f2 && (row = f2(row, n2++)) == null) continue;
|
|
16480
|
+
rows.push(row);
|
|
16481
|
+
}
|
|
16482
|
+
return rows;
|
|
16483
|
+
}
|
|
16484
|
+
function preformatBody(rows, columns) {
|
|
16485
|
+
return rows.map(function(row) {
|
|
16486
|
+
return columns.map(function(column) {
|
|
16487
|
+
return formatValue2(row[column]);
|
|
16488
|
+
}).join(delimiter2);
|
|
16489
|
+
});
|
|
16490
|
+
}
|
|
16491
|
+
function format2(rows, columns) {
|
|
16492
|
+
if (columns == null) columns = inferColumns(rows);
|
|
16493
|
+
return [columns.map(formatValue2).join(delimiter2)].concat(preformatBody(rows, columns)).join("\n");
|
|
16494
|
+
}
|
|
16495
|
+
function formatBody(rows, columns) {
|
|
16496
|
+
if (columns == null) columns = inferColumns(rows);
|
|
16497
|
+
return preformatBody(rows, columns).join("\n");
|
|
16498
|
+
}
|
|
16499
|
+
function formatRows(rows) {
|
|
16500
|
+
return rows.map(formatRow).join("\n");
|
|
16501
|
+
}
|
|
16502
|
+
function formatRow(row) {
|
|
16503
|
+
return row.map(formatValue2).join(delimiter2);
|
|
16504
|
+
}
|
|
16505
|
+
function formatValue2(value) {
|
|
16506
|
+
return value == null ? "" : value instanceof Date ? formatDate(value) : reFormat.test(value += "") ? '"' + value.replace(/"/g, '""') + '"' : value;
|
|
16507
|
+
}
|
|
16508
|
+
return {
|
|
16509
|
+
parse,
|
|
16510
|
+
parseRows,
|
|
16511
|
+
format: format2,
|
|
16512
|
+
formatBody,
|
|
16513
|
+
formatRows,
|
|
16514
|
+
formatRow,
|
|
16515
|
+
formatValue: formatValue2
|
|
16516
|
+
};
|
|
16517
|
+
}
|
|
16518
|
+
|
|
16519
|
+
// node_modules/.pnpm/d3-dsv@3.0.1/node_modules/d3-dsv/src/csv.js
|
|
16520
|
+
var csv = dsv_default(",");
|
|
16521
|
+
var csvParse = csv.parse;
|
|
16522
|
+
var csvParseRows = csv.parseRows;
|
|
16523
|
+
var csvFormat = csv.format;
|
|
16524
|
+
var csvFormatBody = csv.formatBody;
|
|
16525
|
+
var csvFormatRows = csv.formatRows;
|
|
16526
|
+
var csvFormatRow = csv.formatRow;
|
|
16527
|
+
var csvFormatValue = csv.formatValue;
|
|
16528
|
+
|
|
16529
|
+
// node_modules/.pnpm/d3-dsv@3.0.1/node_modules/d3-dsv/src/tsv.js
|
|
16530
|
+
var tsv = dsv_default(" ");
|
|
16531
|
+
var tsvParse = tsv.parse;
|
|
16532
|
+
var tsvParseRows = tsv.parseRows;
|
|
16533
|
+
var tsvFormat = tsv.format;
|
|
16534
|
+
var tsvFormatBody = tsv.formatBody;
|
|
16535
|
+
var tsvFormatRows = tsv.formatRows;
|
|
16536
|
+
var tsvFormatRow = tsv.formatRow;
|
|
16537
|
+
var tsvFormatValue = tsv.formatValue;
|
|
16538
|
+
|
|
16539
|
+
// web-src/views/source-preview-i18n.ts
|
|
16540
|
+
var DELIMITED_PREVIEW_TEXT = {
|
|
16541
|
+
en: (format2) => ({
|
|
16542
|
+
searchLabel: `Search all ${format2.toUpperCase()} columns`,
|
|
16543
|
+
searchPlaceholder: "Search all columns…",
|
|
16544
|
+
resetLabel: "Reset",
|
|
16545
|
+
resetAction: "Clear search, column filters, and sorting",
|
|
16546
|
+
resultCount: (visible, total) => `${visible} / ${total} rows`,
|
|
16547
|
+
resultCountLabel: `Visible ${format2.toUpperCase()} rows`,
|
|
16548
|
+
columnLabel: (index) => `Column ${index}`,
|
|
16549
|
+
columnFilterLabel: (column) => `Filter ${column}`,
|
|
16550
|
+
columnFilterPlaceholder: "Filter…",
|
|
16551
|
+
sortAscending: (column) => `Sort ${column} ascending`,
|
|
16552
|
+
sortDescending: (column) => `Sort ${column} descending`,
|
|
16553
|
+
clearSort: (column) => `Clear sorting for ${column}`,
|
|
16554
|
+
noMatches: "No rows match the current filters."
|
|
16555
|
+
}),
|
|
16556
|
+
ja: (format2) => ({
|
|
16557
|
+
searchLabel: `${format2.toUpperCase()}の全列を検索`,
|
|
16558
|
+
searchPlaceholder: "全列を検索…",
|
|
16559
|
+
resetLabel: "リセット",
|
|
16560
|
+
resetAction: "検索、列フィルタ、並べ替えを解除",
|
|
16561
|
+
resultCount: (visible, total) => `${visible} / ${total} 行`,
|
|
16562
|
+
resultCountLabel: `表示中の${format2.toUpperCase()}行数`,
|
|
16563
|
+
columnLabel: (index) => `列 ${index}`,
|
|
16564
|
+
columnFilterLabel: (column) => `${column}を絞り込み`,
|
|
16565
|
+
columnFilterPlaceholder: "絞り込み…",
|
|
16566
|
+
sortAscending: (column) => `${column}を昇順に並べ替え`,
|
|
16567
|
+
sortDescending: (column) => `${column}を降順に並べ替え`,
|
|
16568
|
+
clearSort: (column) => `${column}の並べ替えを解除`,
|
|
16569
|
+
noMatches: "現在の条件に一致する行はありません。"
|
|
16570
|
+
})
|
|
16571
|
+
};
|
|
16572
|
+
function delimitedPreviewText(language, format2) {
|
|
16573
|
+
return DELIMITED_PREVIEW_TEXT[language](format2);
|
|
16574
|
+
}
|
|
16575
|
+
|
|
16379
16576
|
// web-src/views/source-preview-elements.ts
|
|
16577
|
+
function renderDelimitedPreview(text3, format2, getText = () => delimitedPreviewText("en", format2)) {
|
|
16578
|
+
const preview = Object.assign(
|
|
16579
|
+
document.createElement("div"),
|
|
16580
|
+
{ localize: () => void 0 }
|
|
16581
|
+
);
|
|
16582
|
+
preview.className = "gdp-csv-preview";
|
|
16583
|
+
const parseRows = format2 === "tsv" ? tsvParseRows : csvParseRows;
|
|
16584
|
+
const rows = parseRows(text3.charCodeAt(0) === 65279 ? text3.slice(1) : text3);
|
|
16585
|
+
if (rows.length === 0) return preview;
|
|
16586
|
+
const columnCount = rows.reduce(
|
|
16587
|
+
(largest, row) => Math.max(largest, row.length),
|
|
16588
|
+
0
|
|
16589
|
+
);
|
|
16590
|
+
const dataRows = rows.slice(1).map((row, index) => ({
|
|
16591
|
+
sourceIndex: index + 1,
|
|
16592
|
+
cells: Array.from(
|
|
16593
|
+
{ length: columnCount },
|
|
16594
|
+
(_, column) => row[column] ?? ""
|
|
16595
|
+
)
|
|
16596
|
+
}));
|
|
16597
|
+
const collator = new Intl.Collator(void 0, {
|
|
16598
|
+
numeric: true,
|
|
16599
|
+
sensitivity: "base"
|
|
16600
|
+
});
|
|
16601
|
+
const columnFilters = Array.from({ length: columnCount }, () => "");
|
|
16602
|
+
let sortColumn = null;
|
|
16603
|
+
let sortDirection = null;
|
|
16604
|
+
let visibleCount = dataRows.length;
|
|
16605
|
+
let emptyCell = null;
|
|
16606
|
+
const shell = document.createElement("section");
|
|
16607
|
+
shell.className = "gdp-csv-shell";
|
|
16608
|
+
const toolbar = document.createElement("div");
|
|
16609
|
+
toolbar.className = "gdp-csv-toolbar";
|
|
16610
|
+
const searchIcon = document.createElement("span");
|
|
16611
|
+
searchIcon.className = "gdp-csv-search-icon";
|
|
16612
|
+
searchIcon.setAttribute("aria-hidden", "true");
|
|
16613
|
+
searchIcon.innerHTML = iconSvg("octicon-search", SEARCH_16_PATH);
|
|
16614
|
+
const search = document.createElement("input");
|
|
16615
|
+
search.type = "search";
|
|
16616
|
+
search.className = "gdp-csv-search";
|
|
16617
|
+
search.autocomplete = "off";
|
|
16618
|
+
search.spellcheck = false;
|
|
16619
|
+
const status = document.createElement("span");
|
|
16620
|
+
status.className = "gdp-csv-result-count";
|
|
16621
|
+
status.setAttribute("role", "status");
|
|
16622
|
+
status.setAttribute("aria-live", "polite");
|
|
16623
|
+
const reset = document.createElement("button");
|
|
16624
|
+
reset.type = "button";
|
|
16625
|
+
reset.className = "gdp-csv-reset";
|
|
16626
|
+
toolbar.append(searchIcon, search, status, reset);
|
|
16627
|
+
const table2 = document.createElement("table");
|
|
16628
|
+
table2.className = "gdp-csv-table";
|
|
16629
|
+
const thead = document.createElement("thead");
|
|
16630
|
+
const headRow = document.createElement("tr");
|
|
16631
|
+
const corner = document.createElement("th");
|
|
16632
|
+
corner.className = "gdp-csv-row-number";
|
|
16633
|
+
corner.setAttribute("aria-hidden", "true");
|
|
16634
|
+
headRow.appendChild(corner);
|
|
16635
|
+
const sortHeaders = [];
|
|
16636
|
+
for (let column = 0; column < columnCount; column++) {
|
|
16637
|
+
const th = document.createElement("th");
|
|
16638
|
+
th.scope = "col";
|
|
16639
|
+
const button = document.createElement("button");
|
|
16640
|
+
button.type = "button";
|
|
16641
|
+
button.className = "gdp-csv-sort-button";
|
|
16642
|
+
button.dataset.csvSortColumn = String(column);
|
|
16643
|
+
const label = document.createElement("span");
|
|
16644
|
+
label.textContent = rows[0][column] ?? "";
|
|
16645
|
+
button.appendChild(label);
|
|
16646
|
+
button.addEventListener("click", () => {
|
|
16647
|
+
if (sortColumn !== column) {
|
|
16648
|
+
sortColumn = column;
|
|
16649
|
+
sortDirection = "asc";
|
|
16650
|
+
} else if (sortDirection === "asc") {
|
|
16651
|
+
sortDirection = "desc";
|
|
16652
|
+
} else if (sortDirection === "desc") {
|
|
16653
|
+
sortColumn = null;
|
|
16654
|
+
sortDirection = null;
|
|
16655
|
+
} else {
|
|
16656
|
+
sortDirection = "asc";
|
|
16657
|
+
}
|
|
16658
|
+
renderBody();
|
|
16659
|
+
button.focus();
|
|
16660
|
+
});
|
|
16661
|
+
th.appendChild(button);
|
|
16662
|
+
headRow.appendChild(th);
|
|
16663
|
+
sortHeaders.push({ cell: th, button, label });
|
|
16664
|
+
}
|
|
16665
|
+
thead.appendChild(headRow);
|
|
16666
|
+
const filterRow = document.createElement("tr");
|
|
16667
|
+
filterRow.className = "gdp-csv-filter-row";
|
|
16668
|
+
const filterCorner = document.createElement("th");
|
|
16669
|
+
filterCorner.className = "gdp-csv-row-number";
|
|
16670
|
+
filterCorner.setAttribute("aria-hidden", "true");
|
|
16671
|
+
filterRow.appendChild(filterCorner);
|
|
16672
|
+
const filterInputs = [];
|
|
16673
|
+
for (let column = 0; column < columnCount; column++) {
|
|
16674
|
+
const th = document.createElement("th");
|
|
16675
|
+
const input2 = document.createElement("input");
|
|
16676
|
+
input2.type = "search";
|
|
16677
|
+
input2.className = "gdp-csv-column-filter";
|
|
16678
|
+
input2.dataset.csvColumnFilter = String(column);
|
|
16679
|
+
input2.autocomplete = "off";
|
|
16680
|
+
input2.spellcheck = false;
|
|
16681
|
+
input2.addEventListener("input", () => {
|
|
16682
|
+
columnFilters[column] = input2.value;
|
|
16683
|
+
renderBody();
|
|
16684
|
+
});
|
|
16685
|
+
input2.addEventListener("keydown", (event) => {
|
|
16686
|
+
if (isImeComposing(event) || event.key !== "Escape" || !input2.value)
|
|
16687
|
+
return;
|
|
16688
|
+
input2.value = "";
|
|
16689
|
+
columnFilters[column] = "";
|
|
16690
|
+
renderBody();
|
|
16691
|
+
});
|
|
16692
|
+
th.appendChild(input2);
|
|
16693
|
+
filterRow.appendChild(th);
|
|
16694
|
+
filterInputs.push(input2);
|
|
16695
|
+
}
|
|
16696
|
+
thead.appendChild(filterRow);
|
|
16697
|
+
table2.appendChild(thead);
|
|
16698
|
+
const tbody = document.createElement("tbody");
|
|
16699
|
+
table2.appendChild(tbody);
|
|
16700
|
+
shell.append(toolbar, table2);
|
|
16701
|
+
preview.appendChild(shell);
|
|
16702
|
+
function normalized(value) {
|
|
16703
|
+
return value.trim().toLocaleLowerCase();
|
|
16704
|
+
}
|
|
16705
|
+
function activeStateCount() {
|
|
16706
|
+
return (normalized(search.value) ? 1 : 0) + columnFilters.filter((value) => normalized(value)).length + (sortColumn === null ? 0 : 1);
|
|
16707
|
+
}
|
|
16708
|
+
function localizedColumnLabel(column, textValue) {
|
|
16709
|
+
return rows[0][column] || textValue.columnLabel(column + 1);
|
|
16710
|
+
}
|
|
16711
|
+
function syncLocalizedText() {
|
|
16712
|
+
const textValue = getText();
|
|
16713
|
+
toolbar.setAttribute("aria-label", textValue.searchLabel);
|
|
16714
|
+
search.placeholder = textValue.searchPlaceholder;
|
|
16715
|
+
search.setAttribute("aria-label", textValue.searchLabel);
|
|
16716
|
+
reset.textContent = textValue.resetLabel;
|
|
16717
|
+
reset.title = textValue.resetAction;
|
|
16718
|
+
reset.setAttribute("aria-label", textValue.resetAction);
|
|
16719
|
+
status.textContent = textValue.resultCount(visibleCount, dataRows.length);
|
|
16720
|
+
status.setAttribute("aria-label", textValue.resultCountLabel);
|
|
16721
|
+
if (emptyCell) emptyCell.textContent = textValue.noMatches;
|
|
16722
|
+
sortHeaders.forEach(({ cell, button }, column) => {
|
|
16723
|
+
const columnLabel = localizedColumnLabel(column, textValue);
|
|
16724
|
+
const active = sortColumn === column ? sortDirection : null;
|
|
16725
|
+
cell.setAttribute(
|
|
16726
|
+
"aria-sort",
|
|
16727
|
+
active === "asc" ? "ascending" : active === "desc" ? "descending" : "none"
|
|
16728
|
+
);
|
|
16729
|
+
button.dataset.sortDirection = active ?? "none";
|
|
16730
|
+
const action = active === "asc" ? textValue.sortDescending(columnLabel) : active === "desc" ? textValue.clearSort(columnLabel) : textValue.sortAscending(columnLabel);
|
|
16731
|
+
button.title = action;
|
|
16732
|
+
button.setAttribute("aria-label", action);
|
|
16733
|
+
});
|
|
16734
|
+
filterInputs.forEach((input2, column) => {
|
|
16735
|
+
const columnLabel = localizedColumnLabel(column, textValue);
|
|
16736
|
+
input2.placeholder = textValue.columnFilterPlaceholder;
|
|
16737
|
+
input2.setAttribute(
|
|
16738
|
+
"aria-label",
|
|
16739
|
+
textValue.columnFilterLabel(columnLabel)
|
|
16740
|
+
);
|
|
16741
|
+
});
|
|
16742
|
+
}
|
|
16743
|
+
function renderBody() {
|
|
16744
|
+
const globalQuery = normalized(search.value);
|
|
16745
|
+
const filters = columnFilters.map(normalized);
|
|
16746
|
+
const filtered = dataRows.filter(
|
|
16747
|
+
(row) => (!globalQuery || row.cells.some(
|
|
16748
|
+
(cell) => cell.toLocaleLowerCase().includes(globalQuery)
|
|
16749
|
+
)) && filters.every(
|
|
16750
|
+
(filter, column) => !filter || row.cells[column].toLocaleLowerCase().includes(filter)
|
|
16751
|
+
)
|
|
16752
|
+
);
|
|
16753
|
+
const visibleRows = sortColumn === null || sortDirection === null ? filtered : [...filtered].sort((a2, b2) => {
|
|
16754
|
+
const aValue = a2.cells[sortColumn];
|
|
16755
|
+
const bValue = b2.cells[sortColumn];
|
|
16756
|
+
if (!aValue && bValue) return 1;
|
|
16757
|
+
if (aValue && !bValue) return -1;
|
|
16758
|
+
const compared = collator.compare(aValue, bValue);
|
|
16759
|
+
if (compared === 0) return a2.sourceIndex - b2.sourceIndex;
|
|
16760
|
+
return sortDirection === "asc" ? compared : -compared;
|
|
16761
|
+
});
|
|
16762
|
+
tbody.replaceChildren();
|
|
16763
|
+
emptyCell = null;
|
|
16764
|
+
for (const row of visibleRows) {
|
|
16765
|
+
const tr = document.createElement("tr");
|
|
16766
|
+
const rowNumber = document.createElement("th");
|
|
16767
|
+
rowNumber.className = "gdp-csv-row-number";
|
|
16768
|
+
rowNumber.scope = "row";
|
|
16769
|
+
rowNumber.textContent = String(row.sourceIndex);
|
|
16770
|
+
tr.appendChild(rowNumber);
|
|
16771
|
+
for (const value of row.cells) {
|
|
16772
|
+
const td = document.createElement("td");
|
|
16773
|
+
td.textContent = value;
|
|
16774
|
+
tr.appendChild(td);
|
|
16775
|
+
}
|
|
16776
|
+
tbody.appendChild(tr);
|
|
16777
|
+
}
|
|
16778
|
+
if (visibleRows.length === 0) {
|
|
16779
|
+
const tr = document.createElement("tr");
|
|
16780
|
+
tr.className = "gdp-csv-empty-row";
|
|
16781
|
+
emptyCell = document.createElement("td");
|
|
16782
|
+
emptyCell.colSpan = columnCount + 1;
|
|
16783
|
+
tr.appendChild(emptyCell);
|
|
16784
|
+
tbody.appendChild(tr);
|
|
16785
|
+
}
|
|
16786
|
+
visibleCount = visibleRows.length;
|
|
16787
|
+
reset.disabled = activeStateCount() === 0;
|
|
16788
|
+
syncLocalizedText();
|
|
16789
|
+
}
|
|
16790
|
+
search.addEventListener("input", renderBody);
|
|
16791
|
+
search.addEventListener("keydown", (event) => {
|
|
16792
|
+
if (isImeComposing(event) || event.key !== "Escape" || !search.value)
|
|
16793
|
+
return;
|
|
16794
|
+
search.value = "";
|
|
16795
|
+
renderBody();
|
|
16796
|
+
});
|
|
16797
|
+
reset.addEventListener("click", () => {
|
|
16798
|
+
search.value = "";
|
|
16799
|
+
columnFilters.fill("");
|
|
16800
|
+
filterInputs.forEach((input2) => {
|
|
16801
|
+
input2.value = "";
|
|
16802
|
+
});
|
|
16803
|
+
sortColumn = null;
|
|
16804
|
+
sortDirection = null;
|
|
16805
|
+
renderBody();
|
|
16806
|
+
search.focus();
|
|
16807
|
+
});
|
|
16808
|
+
preview.localize = syncLocalizedText;
|
|
16809
|
+
renderBody();
|
|
16810
|
+
return preview;
|
|
16811
|
+
}
|
|
16380
16812
|
function renderHtmlPreviewFrame(title, html, extraClass = "") {
|
|
16381
16813
|
const preview = document.createElement("div");
|
|
16382
16814
|
preview.className = ["gdp-html-preview", extraClass].filter(Boolean).join(" ");
|
|
@@ -17106,6 +17538,8 @@ Details: ${JSON.stringify(output)}` : "";
|
|
|
17106
17538
|
data.text,
|
|
17107
17539
|
"s3-html-preview"
|
|
17108
17540
|
);
|
|
17541
|
+
} else if (previewKind === "csv" || previewKind === "tsv") {
|
|
17542
|
+
body = renderDelimitedPreview(data.text, previewKind);
|
|
17109
17543
|
} else if (previewKind === "markdown") {
|
|
17110
17544
|
body = await renderMarkdownPreview(
|
|
17111
17545
|
data.text,
|
|
@@ -18166,8 +18600,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
18166
18600
|
}
|
|
18167
18601
|
function formatTime2(timestamp) {
|
|
18168
18602
|
const d2 = new Date(timestamp);
|
|
18169
|
-
const
|
|
18170
|
-
return `${
|
|
18603
|
+
const pad2 = (n2) => String(n2).padStart(2, "0");
|
|
18604
|
+
return `${pad2(d2.getHours())}:${pad2(d2.getMinutes())}:${pad2(d2.getSeconds())}`;
|
|
18171
18605
|
}
|
|
18172
18606
|
|
|
18173
18607
|
// web-src/views/database/snapshot-view.ts
|
|
@@ -26510,8 +26944,8 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
26510
26944
|
const t2 = Date.parse(iso);
|
|
26511
26945
|
if (!Number.isFinite(t2)) return iso;
|
|
26512
26946
|
const d2 = new Date(t2);
|
|
26513
|
-
const
|
|
26514
|
-
return `${d2.getFullYear()}-${
|
|
26947
|
+
const pad2 = (n2) => String(n2).padStart(2, "0");
|
|
26948
|
+
return `${d2.getFullYear()}-${pad2(d2.getMonth() + 1)}-${pad2(d2.getDate())} ${pad2(d2.getHours())}:${pad2(d2.getMinutes())}`;
|
|
26515
26949
|
}
|
|
26516
26950
|
function displayWhen(iso) {
|
|
26517
26951
|
const relative = relativeWhen(iso);
|
|
@@ -28054,6 +28488,10 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
28054
28488
|
kind: "paragraph",
|
|
28055
28489
|
text: "A file detail page exposes up to four tabs — Preview, Code, Blame, History. For text files Code is the default and ?preview=1 opts in to the Markdown / HTML preview; media files (images, video, audio, PDF) show a Preview tab only, with no Code tab. Blame and History have their own canonical URLs (view=blame, view=history) so deep links and the browser back/forward stay in sync, and they keep the Repository sidebar visible. Opening another file from the repository tree keeps the active tab (a file that cannot be previewed falls back to Code)."
|
|
28056
28490
|
},
|
|
28491
|
+
{
|
|
28492
|
+
kind: "paragraph",
|
|
28493
|
+
text: "CSV and TSV previews provide all-column search, per-column filters, three-state column sorting (ascending, descending, then source order), a visible-row count, and a reset action. Filtering and sorting keep each row's original file row number."
|
|
28494
|
+
},
|
|
28057
28495
|
{
|
|
28058
28496
|
kind: "paragraph",
|
|
28059
28497
|
text: "Relative links inside a Markdown preview lead to the same destinations as they do on GitHub: another Markdown file opens its file page, an #anchor opens the preview and scrolls to that heading, a non-Markdown file opens in the Code view, and a link to a directory opens that folder in the repository tree."
|
|
@@ -28784,6 +29222,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
28784
29222
|
kind: "paragraph",
|
|
28785
29223
|
text: "ファイル詳細ページには最大 4 つのタブ (Preview / Code / Blame / History) があります。テキストファイルは Code がデフォルトで、?preview=1 を付けると Markdown / HTML プレビューに切り替わります。画像・動画・音声・PDF などのメディアファイルは Preview タブのみ表示され、Code タブは表示されません。Blame と History はそれぞれ専用 URL (view=blame, view=history) を持つため、ディープリンクとブラウザの戻る / 進むが同期し、いずれも Repository サイドバーは表示されたままです。ツリーから別のファイルを開いても選択中のタブは維持されます (プレビューできないファイルでは Code に戻ります)。"
|
|
28786
29224
|
},
|
|
29225
|
+
{
|
|
29226
|
+
kind: "paragraph",
|
|
29227
|
+
text: "CSV・TSVプレビューでは、全列検索、列ごとの絞り込み、昇順・降順・元の順番の3段階ソート、表示件数、リセットを利用できます。絞り込みや並べ替えの後も、各行には元ファイル上の行番号が表示されます。"
|
|
29228
|
+
},
|
|
28787
29229
|
{
|
|
28788
29230
|
kind: "paragraph",
|
|
28789
29231
|
text: "Markdown プレビュー内の相対リンクは GitHub と同じ行き先に解決されます。別の Markdown ファイルはそのファイルページを開き、#見出し 付きのリンクはプレビューを開いて該当見出しまでスクロールし、Markdown 以外のファイルは Code ビュー、ディレクトリへのリンクはリポジトリツリーのそのフォルダを開きます。"
|
|
@@ -32497,8 +32939,8 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
32497
32939
|
const t2 = Date.parse(iso);
|
|
32498
32940
|
if (!Number.isFinite(t2)) return iso;
|
|
32499
32941
|
const d2 = new Date(t2);
|
|
32500
|
-
const
|
|
32501
|
-
return `${d2.getFullYear()}-${
|
|
32942
|
+
const pad2 = (n2) => String(n2).padStart(2, "0");
|
|
32943
|
+
return `${d2.getFullYear()}-${pad2(d2.getMonth() + 1)}-${pad2(d2.getDate())} ${pad2(d2.getHours())}:${pad2(d2.getMinutes())}`;
|
|
32502
32944
|
}
|
|
32503
32945
|
function displayWhen(iso) {
|
|
32504
32946
|
const relative = relativeWhen(iso);
|
|
@@ -36872,7 +37314,8 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
36872
37314
|
setViewFileButtonState,
|
|
36873
37315
|
scrollMainPanel,
|
|
36874
37316
|
focusMainSurface,
|
|
36875
|
-
isPaletteOpen
|
|
37317
|
+
isPaletteOpen,
|
|
37318
|
+
getLanguage
|
|
36876
37319
|
} = deps;
|
|
36877
37320
|
function markdownLinkNavigationDeps() {
|
|
36878
37321
|
return {
|
|
@@ -37189,15 +37632,10 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37189
37632
|
function setPreferredSourceTab(tab) {
|
|
37190
37633
|
PREFERRED_SOURCE_TAB = tab;
|
|
37191
37634
|
}
|
|
37192
|
-
function
|
|
37193
|
-
if (!previewable)
|
|
37194
|
-
PREFERRED_SOURCE_TAB = null;
|
|
37195
|
-
return "code";
|
|
37196
|
-
}
|
|
37635
|
+
function preferredSourceTabFor(previewable) {
|
|
37636
|
+
if (!previewable) return "code";
|
|
37197
37637
|
const routeTab = STATE.route.screen === "file" && STATE.route.view === "blob" && STATE.route.preview ? "preview" : "code";
|
|
37198
|
-
|
|
37199
|
-
PREFERRED_SOURCE_TAB = null;
|
|
37200
|
-
return tab;
|
|
37638
|
+
return PREFERRED_SOURCE_TAB || routeTab;
|
|
37201
37639
|
}
|
|
37202
37640
|
let SOURCE_REQ_SEQ = 0;
|
|
37203
37641
|
let ACTIVE_SOURCE_LOAD = null;
|
|
@@ -37449,7 +37887,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37449
37887
|
if (signal?.aborted) return false;
|
|
37450
37888
|
const previewable = isPreviewableSource(target.path);
|
|
37451
37889
|
const previewKind = sourcePreviewKind(target.path);
|
|
37452
|
-
const initialSourceTab =
|
|
37890
|
+
const initialSourceTab = preferredSourceTabFor(previewable);
|
|
37453
37891
|
const tabsHost = card.querySelector(".gdp-file-detail-tabs");
|
|
37454
37892
|
if (usesVirtualSource) {
|
|
37455
37893
|
const virtualCode = renderVirtualSource(
|
|
@@ -37471,7 +37909,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37471
37909
|
tabsHost.hidden = false;
|
|
37472
37910
|
tabsHost.replaceChildren(tabs3);
|
|
37473
37911
|
}
|
|
37474
|
-
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) :
|
|
37912
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : previewKind === "csv" || previewKind === "tsv" ? renderDelimitedPreview(
|
|
37913
|
+
textValue,
|
|
37914
|
+
previewKind,
|
|
37915
|
+
() => delimitedPreviewText(getLanguage(), previewKind)
|
|
37916
|
+
) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(
|
|
37475
37917
|
textValue,
|
|
37476
37918
|
target,
|
|
37477
37919
|
{
|
|
@@ -37484,7 +37926,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37484
37926
|
preview.dataset.sourcePane = "preview";
|
|
37485
37927
|
let previewHighlightScheduled = false;
|
|
37486
37928
|
const ensurePreviewHighlight = () => {
|
|
37487
|
-
if (previewKind
|
|
37929
|
+
if (previewKind !== "markdown" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
37488
37930
|
return;
|
|
37489
37931
|
previewHighlightScheduled = true;
|
|
37490
37932
|
scheduleMarkdownPreviewHighlight(
|
|
@@ -37591,7 +38033,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37591
38033
|
tabsHost.replaceChildren(tabs);
|
|
37592
38034
|
}
|
|
37593
38035
|
if (previewable) {
|
|
37594
|
-
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) :
|
|
38036
|
+
let preview = previewKind === "html" ? renderHtmlPreview(target, textValue) : previewKind === "csv" || previewKind === "tsv" ? renderDelimitedPreview(
|
|
38037
|
+
textValue,
|
|
38038
|
+
previewKind,
|
|
38039
|
+
() => delimitedPreviewText(getLanguage(), previewKind)
|
|
38040
|
+
) : await (deps.renderMarkdownPreview ?? renderMarkdownPreview)(
|
|
37595
38041
|
textValue,
|
|
37596
38042
|
target,
|
|
37597
38043
|
{
|
|
@@ -37604,7 +38050,7 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
37604
38050
|
preview.dataset.sourcePane = "preview";
|
|
37605
38051
|
let previewHighlightScheduled = false;
|
|
37606
38052
|
const ensurePreviewHighlight = () => {
|
|
37607
|
-
if (previewKind
|
|
38053
|
+
if (previewKind !== "markdown" || !STATE.syntaxHighlight || previewHighlightScheduled)
|
|
37608
38054
|
return;
|
|
37609
38055
|
previewHighlightScheduled = true;
|
|
37610
38056
|
scheduleMarkdownPreviewHighlight(
|
|
@@ -38770,6 +39216,11 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38770
39216
|
function handleVirtualSourcePagingKeydown(e2) {
|
|
38771
39217
|
handleVirtualSourcePagingKey(e2, e2.target);
|
|
38772
39218
|
}
|
|
39219
|
+
function localize() {
|
|
39220
|
+
document.querySelectorAll(".gdp-csv-preview").forEach((preview) => {
|
|
39221
|
+
preview.localize();
|
|
39222
|
+
});
|
|
39223
|
+
}
|
|
38773
39224
|
return {
|
|
38774
39225
|
renderStandaloneSource,
|
|
38775
39226
|
applySourceRouteToShell,
|
|
@@ -38804,7 +39255,8 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
38804
39255
|
loadSourceShikiHighlighter,
|
|
38805
39256
|
sourceShikiLines,
|
|
38806
39257
|
shouldVirtualizeSource,
|
|
38807
|
-
inferLang
|
|
39258
|
+
inferLang,
|
|
39259
|
+
localize
|
|
38808
39260
|
};
|
|
38809
39261
|
}
|
|
38810
39262
|
|
|
@@ -39746,17 +40198,6 @@ code-viewer annotate add-db --db app.db --tab query \\
|
|
|
39746
40198
|
return null;
|
|
39747
40199
|
}
|
|
39748
40200
|
|
|
39749
|
-
// web-src/core/lazy-bundle.ts
|
|
39750
|
-
function createBundleLoader(bundleFile, init) {
|
|
39751
|
-
let pending = null;
|
|
39752
|
-
return () => {
|
|
39753
|
-
if (!pending) {
|
|
39754
|
-
pending = import(`/${bundleFile}`).then((mod) => init ? init(mod) : mod).catch(() => null);
|
|
39755
|
-
}
|
|
39756
|
-
return pending;
|
|
39757
|
-
};
|
|
39758
|
-
}
|
|
39759
|
-
|
|
39760
40201
|
// web-src/core/xterm-loader.ts
|
|
39761
40202
|
var loadXterm = createBundleLoader("xterm.js");
|
|
39762
40203
|
|
|
@@ -42833,7 +43274,8 @@ ${formatErrorDetail(error2)}`);
|
|
|
42833
43274
|
setViewFileButtonState: (button, sourceMode) => DIFF_VIEW.setViewFileButtonState(button, sourceMode),
|
|
42834
43275
|
scrollMainPanel,
|
|
42835
43276
|
focusMainSurface,
|
|
42836
|
-
isPaletteOpen: () => SEARCH_PALETTE.isPaletteOpen()
|
|
43277
|
+
isPaletteOpen: () => SEARCH_PALETTE.isPaletteOpen(),
|
|
43278
|
+
getLanguage: () => STATE.language
|
|
42837
43279
|
});
|
|
42838
43280
|
const {
|
|
42839
43281
|
renderStandaloneSource,
|
|
@@ -43793,6 +44235,7 @@ ${formatErrorDetail(error2)}`);
|
|
|
43793
44235
|
relocalizeHistory?.();
|
|
43794
44236
|
relocalizeJournal?.();
|
|
43795
44237
|
relocalizeViewerSettings?.();
|
|
44238
|
+
SOURCE_VIEW.localize();
|
|
43796
44239
|
setElementText(".annotation-panel-head strong", text3.annotations.title);
|
|
43797
44240
|
const followLabel = document.querySelector(
|
|
43798
44241
|
".annotation-follow-label"
|