@simon_he/vue-tui 1.1.5 → 1.1.7
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 +1 -0
- package/dist/TAgentTerminalGraphic-B8-YZfuP.js +1198 -0
- package/dist/{TSelect-CMBOOFwK.js → TSelect-CCsjjCOr.js} +41 -12
- package/dist/{TTree-kk8ntrpg.js → TTree-3W5A2_EH.js} +4 -3
- package/dist/TVideo-D9AOiyq2.js +948 -0
- package/dist/agent.cjs +5204 -4312
- package/dist/agent.js +11 -9
- package/dist/{block-source-DhzajB9H.js → block-source-BhvdZomx.js} +246 -53
- package/dist/cli.cjs +41 -26
- package/dist/cli.js +68 -18
- package/dist/core.js +2 -2
- package/dist/experimental/browser.cjs +3705 -0
- package/dist/experimental/browser.d.cts +3 -0
- package/dist/experimental/browser.d.ts +3 -0
- package/dist/experimental/browser.js +413 -0
- package/dist/experimental.cjs +2 -1
- package/dist/experimental.js +9 -947
- package/dist/{linkify-CL9wwnZN.js → frame-mailbox-DaTrfyaF.js} +2 -297
- package/dist/index.cjs +25 -8
- package/dist/index.js +6 -5
- package/dist/linkify-CklfA1vp.js +298 -0
- package/dist/markdown.cjs +5196 -4322
- package/dist/markdown.js +4 -4
- package/dist/{mermaid-N3kGTHFy.js → mermaid-D0ov4_A1.js} +93 -9
- package/dist/mermaid.cjs +78 -7
- package/dist/mermaid.js +4 -4
- package/dist/{path-suggest-Dndu4dTi.js → path-suggest-fPzRsgPv.js} +1 -1
- package/dist/renderer/terminal-graphics.d.ts +1 -1
- package/dist/{terminal-graphics-2FTRg9x3.js → terminal-graphics-DpSL29OQ.js} +3 -3
- package/dist/{tlog-theme-B91Wv7Zj.js → tlog-theme-BnILsD3n.js} +10 -1203
- package/dist/vue/browser/types.d.ts +52 -0
- package/dist/vue/components/TAgentTerminalGraphic.d.ts +3 -0
- package/dist/vue/components/TBrowser.d.ts +231 -0
- package/dist/vue/components/TVirtualMarkdown.d.ts +10 -0
- package/dist/vue/markdown/render.d.ts +18 -1
- package/dist/vue.cjs +25 -8
- package/dist/vue.js +8 -7
- package/package.json +27 -2
- /package/dist/{TMermaidText-wLnMMvVS.js → TMermaidText-C1akgJPU.js} +0 -0
- /package/dist/{math-image-BZhmfUeu.js → math-image-CcUpBnW0.js} +0 -0
- /package/dist/{path-mnSgEpCm.js → path-BI9W15Zt.js} +0 -0
- /package/dist/{wheel-scroll-DASkEZr-.js → wheel-scroll-CQ22Hcyj.js} +0 -0
package/dist/agent.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import "./create-terminal-Db_-UGVQ.js";
|
|
2
2
|
import "./hyperlink-clbb_ha_.js";
|
|
3
3
|
import { forEachTextCellSegment, recordTerminalGraphicTrace, sanitizeInlineText, sanitizeTextBlock, sliceByCells, spaces, textCellWidth$1 as textCellWidth, useTerminal, withTextWidthProvider } from "./rect-JzWMJxxc.js";
|
|
4
|
-
import
|
|
4
|
+
import "./linkify-CklfA1vp.js";
|
|
5
5
|
import "./frame-perf-CHpWhbC4.js";
|
|
6
6
|
import "./env-Cl8qmNFN.js";
|
|
7
7
|
import "./terminal-selection-4W1SJj4c.js";
|
|
8
8
|
import "./debug-logger-CmsGI4of.js";
|
|
9
|
-
import { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-
|
|
10
|
-
import "./
|
|
11
|
-
import "./
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import "./
|
|
16
|
-
import
|
|
9
|
+
import { TBox, TCommandPalette, TDialog, TInput, TRenderPlane, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-CCsjjCOr.js";
|
|
10
|
+
import { TText, TView } from "./frame-mailbox-DaTrfyaF.js";
|
|
11
|
+
import "./path-BI9W15Zt.js";
|
|
12
|
+
import "./wheel-scroll-CQ22Hcyj.js";
|
|
13
|
+
import { TMermaid$1 as TMermaid, TMermaidText$1 as TMermaidText, isSimpleMermaidFlowchartSource, markMermaidRenderErrorFatal } from "./TMermaidText-C1akgJPU.js";
|
|
14
|
+
import { createIterm2InlineImageSequence, createKittyDeleteGraphicsSequence, createKittyGraphicsSequence, createKittyPlacementSequence, createTerminalGraphicPngSequence, detectTerminalGraphicsCapabilities, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, hashTerminalGraphicsString, isSafeTerminalGraphicsSequence, normalizeTerminalGraphicSize, sanitizeTerminalFallbackText, subscribeTerminalGraphicsOutput } from "./terminal-graphics-DpSL29OQ.js";
|
|
15
|
+
import { TVirtualMarkdown, createMarkdownBlockSource } from "./block-source-BhvdZomx.js";
|
|
16
|
+
import "./math-image-CcUpBnW0.js";
|
|
17
|
+
import { TLogLinksPanel, TLogMinimap, TLogScrollbar, TLogSearchBar, TLogSearchPager, TLogSearchResults, TLogView, TLogVirtualLinksPanel, TLogVirtualSearchResults, TTranscriptView, TVirtualList, createAppendOnlyLogStore, createTLogDensityBucketsFromMarkers, createTLogLevelPlugin, createTLogLineMatcherPlugin, createTLogLinkActionPlugin, createTLogOsc8LinkPlugin, createTLogUrlPlugin, detectTLogUrls, dispatchTLogPluginLinkAction, getTLogPluginMetadata, parseTLogAnnotatedText, resolveTLogLinksPanelTheme, resolveTLogMinimapTheme, resolveTLogScrollbarTheme, resolveTLogSearchBarTheme, resolveTLogSearchPagerTheme, resolveTLogSearchResultsTheme, resolveTLogViewTheme, stripTLogAnsiText, tlogDarkPreset, tlogDarkTheme, tlogDefaultPreset, tlogDefaultTheme, tlogHighContrastPreset, tlogHighContrastTheme, toTLogExternalLinkFromVisibleLink, useTLogLinkController, useTLogRetainedIndex, useTLogSearchController, useTLogSearchResultsPage, useTLogVirtualSearchResults } from "./tlog-theme-BnILsD3n.js";
|
|
18
|
+
import { TAgentTerminalGraphic } from "./TAgentTerminalGraphic-B8-YZfuP.js";
|
|
17
19
|
import { computed, defineComponent, h } from "vue";
|
|
18
20
|
|
|
19
21
|
//#region src/vue/agent/view-models.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { hasEncodedControl, sanitizeDomHref } from "./hyperlink-clbb_ha_.js";
|
|
2
|
-
import { EventZIndexContextKey, currentTextWidthProvider, forEachTextCellSegment, intersectRect, normalizeCellRect, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider } from "./rect-JzWMJxxc.js";
|
|
2
|
+
import { EventZIndexContextKey, RenderPlaneContextKey, currentTextWidthProvider, forEachTextCellSegment, intersectRect, normalizeCellRect, repeatChar, sanitizeInlineText, sanitizeTextBlock, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility, withTextWidthProvider } from "./rect-JzWMJxxc.js";
|
|
3
3
|
import { terminalSelectionRowSpans, terminalSelectionVisibleRowSpans } from "./terminal-selection-4W1SJj4c.js";
|
|
4
4
|
import { createDebugLogger, isDebugEnabled } from "./debug-logger-CmsGI4of.js";
|
|
5
|
-
import { applyWheelScroll, createWheelScrollState, resetWheelScrollState } from "./wheel-scroll-
|
|
6
|
-
import { createIterm2InlineImageSequence, createKittyDeleteGraphicsSequence, createKittyGraphicsSequence, createKittyPlacementSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, isTerminalGraphicsProtocol, stableTerminalGraphicNumericId, subscribeTerminalGraphicsOutput } from "./terminal-graphics-
|
|
7
|
-
import { enqueueMarkdownMathImages, getCachedMarkdownMathImage, isMarkdownMathImageRendererReady, loadMarkdownMathImageRenderer, resolveMarkdownMathColor, subscribeMarkdownMathImage } from "./math-image-
|
|
5
|
+
import { applyWheelScroll, createWheelScrollState, resetWheelScrollState } from "./wheel-scroll-CQ22Hcyj.js";
|
|
6
|
+
import { createIterm2InlineImageSequence, createKittyDeleteGraphicsSequence, createKittyGraphicsSequence, createKittyPlacementSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, isTerminalGraphicsProtocol, stableTerminalGraphicNumericId, subscribeTerminalGraphicsOutput } from "./terminal-graphics-DpSL29OQ.js";
|
|
7
|
+
import { enqueueMarkdownMathImages, getCachedMarkdownMathImage, isMarkdownMathImageRendererReady, loadMarkdownMathImageRenderer, resolveMarkdownMathColor, subscribeMarkdownMathImage } from "./math-image-CcUpBnW0.js";
|
|
8
8
|
import { computed, defineComponent, getCurrentInstance, h, inject, markRaw, onBeforeUnmount, ref, shallowRef, watch, watchEffect } from "vue";
|
|
9
9
|
import { getMarkdown, parseMarkdownToStructure } from "stream-markdown-parser";
|
|
10
10
|
|
|
@@ -1696,8 +1696,70 @@ function mergeStyle(base, overlay) {
|
|
|
1696
1696
|
return merged;
|
|
1697
1697
|
}
|
|
1698
1698
|
const activeMarkdownImageGraphics = new WeakMap();
|
|
1699
|
+
const markdownImageGraphicIdCache = new WeakMap();
|
|
1700
|
+
const preparedMarkdownImageGraphicCache = new WeakMap();
|
|
1699
1701
|
function markdownImageGraphicId(segment, identity) {
|
|
1700
|
-
|
|
1702
|
+
let cachedIds = markdownImageGraphicIdCache.get(segment);
|
|
1703
|
+
if (!cachedIds) {
|
|
1704
|
+
cachedIds = new Map();
|
|
1705
|
+
markdownImageGraphicIdCache.set(segment, cachedIds);
|
|
1706
|
+
}
|
|
1707
|
+
const cached = cachedIds.get(identity);
|
|
1708
|
+
if (cached) return cached;
|
|
1709
|
+
const id = `md-image:${stableTerminalGraphicNumericId(`${identity}:${segment.src ?? segment.tex ?? ""}:${segment.displayWidth ?? 0}:${segment.displayHeight ?? 0}:${segment.base64 ?? ""}`)}`;
|
|
1710
|
+
cachedIds.set(identity, id);
|
|
1711
|
+
return id;
|
|
1712
|
+
}
|
|
1713
|
+
function prepareMarkdownImageGraphic(segment, identity, protocol, placement) {
|
|
1714
|
+
if (!segment.base64) return null;
|
|
1715
|
+
let preparedByVariant = preparedMarkdownImageGraphicCache.get(segment);
|
|
1716
|
+
if (!preparedByVariant) {
|
|
1717
|
+
preparedByVariant = new Map();
|
|
1718
|
+
preparedMarkdownImageGraphicCache.set(segment, preparedByVariant);
|
|
1719
|
+
}
|
|
1720
|
+
const cacheKey = `${identity}\u0000${protocol}\u0000${placement.width}\u0000${placement.height}\u0000${placement.sourceX ?? ""}\u0000${placement.sourceY ?? ""}\u0000${placement.sourceWidth ?? ""}\u0000${placement.sourceHeight ?? ""}`;
|
|
1721
|
+
const cached = preparedByVariant.get(cacheKey);
|
|
1722
|
+
if (cached) return cached;
|
|
1723
|
+
const id = markdownImageGraphicId(segment, identity);
|
|
1724
|
+
const imageId = stableTerminalGraphicNumericId(`image:${id}`);
|
|
1725
|
+
const placementId = stableTerminalGraphicNumericId(`placement:${id}`);
|
|
1726
|
+
const sequence = protocol === "kitty" ? createKittyGraphicsSequence(segment.base64, {
|
|
1727
|
+
imageId,
|
|
1728
|
+
placementId,
|
|
1729
|
+
columns: placement.width,
|
|
1730
|
+
rows: placement.height,
|
|
1731
|
+
sourceX: placement.sourceX,
|
|
1732
|
+
sourceY: placement.sourceY,
|
|
1733
|
+
sourceWidth: placement.sourceWidth,
|
|
1734
|
+
sourceHeight: placement.sourceHeight,
|
|
1735
|
+
zIndex: -1
|
|
1736
|
+
}) : protocol === "iterm2" ? createIterm2InlineImageSequence(segment.base64, {
|
|
1737
|
+
width: placement.width,
|
|
1738
|
+
height: placement.height,
|
|
1739
|
+
preserveAspectRatio: true,
|
|
1740
|
+
doNotMoveCursor: true
|
|
1741
|
+
}) : "";
|
|
1742
|
+
if (!sequence) return null;
|
|
1743
|
+
const prepared = Object.freeze({
|
|
1744
|
+
id,
|
|
1745
|
+
sequence,
|
|
1746
|
+
clearSequence: protocol === "kitty" ? createKittyDeleteGraphicsSequence({
|
|
1747
|
+
imageId,
|
|
1748
|
+
placementId
|
|
1749
|
+
}) : void 0,
|
|
1750
|
+
resizeSequence: protocol === "kitty" ? createKittyPlacementSequence({
|
|
1751
|
+
imageId,
|
|
1752
|
+
placementId,
|
|
1753
|
+
columns: placement.width,
|
|
1754
|
+
rows: placement.height,
|
|
1755
|
+
sourceX: placement.sourceX,
|
|
1756
|
+
sourceY: placement.sourceY,
|
|
1757
|
+
sourceWidth: placement.sourceWidth,
|
|
1758
|
+
sourceHeight: placement.sourceHeight
|
|
1759
|
+
}) : void 0
|
|
1760
|
+
});
|
|
1761
|
+
preparedByVariant.set(cacheKey, prepared);
|
|
1762
|
+
return prepared;
|
|
1701
1763
|
}
|
|
1702
1764
|
function rememberMarkdownImageGraphic(terminal, id, rect) {
|
|
1703
1765
|
let active = activeMarkdownImageGraphics.get(terminal);
|
|
@@ -1736,57 +1798,36 @@ function clearMarkdownImageGraphics(terminal, rect) {
|
|
|
1736
1798
|
clearTrackedMarkdownImageGraphic(terminal, id);
|
|
1737
1799
|
}
|
|
1738
1800
|
}
|
|
1739
|
-
function queueMarkdownImageGraphic(terminal, segment, identity, rect) {
|
|
1801
|
+
function queueMarkdownImageGraphic(terminal, segment, identity, rect, placementOverride) {
|
|
1740
1802
|
if (!segment.base64) return "unavailable";
|
|
1741
1803
|
const output = getTerminalGraphicsOutput(terminal);
|
|
1742
1804
|
const protocol = output?.capabilities.preferredProtocol;
|
|
1743
1805
|
if (!output?.capabilities.supported || !isTerminalGraphicsProtocol(protocol)) return "unavailable";
|
|
1744
|
-
const
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1750
|
-
imageId,
|
|
1751
|
-
placementId,
|
|
1752
|
-
columns: width,
|
|
1753
|
-
rows: height,
|
|
1754
|
-
zIndex: -1
|
|
1755
|
-
}) : protocol === "iterm2" ? createIterm2InlineImageSequence(segment.base64, {
|
|
1756
|
-
width,
|
|
1757
|
-
height,
|
|
1758
|
-
preserveAspectRatio: true,
|
|
1759
|
-
doNotMoveCursor: true
|
|
1760
|
-
}) : "";
|
|
1761
|
-
if (!sequence) return "unavailable";
|
|
1762
|
-
const clearSequence = protocol === "kitty" ? createKittyDeleteGraphicsSequence({
|
|
1763
|
-
imageId,
|
|
1764
|
-
placementId
|
|
1765
|
-
}) : void 0;
|
|
1766
|
-
const resizeSequence = protocol === "kitty" ? createKittyPlacementSequence({
|
|
1767
|
-
imageId,
|
|
1768
|
-
placementId,
|
|
1769
|
-
columns: width,
|
|
1770
|
-
rows: height
|
|
1771
|
-
}) : void 0;
|
|
1806
|
+
const placement = placementOverride ?? {
|
|
1807
|
+
width: Math.max(1, Math.floor(segment.displayWidth ?? rect.w)),
|
|
1808
|
+
height: Math.max(1, Math.floor(segment.displayHeight ?? 1))
|
|
1809
|
+
};
|
|
1810
|
+
const prepared = prepareMarkdownImageGraphic(segment, identity, protocol, placement);
|
|
1811
|
+
if (!prepared) return "unavailable";
|
|
1772
1812
|
const accepted = output.queue({
|
|
1773
|
-
id,
|
|
1813
|
+
id: prepared.id,
|
|
1774
1814
|
x: rect.x,
|
|
1775
1815
|
y: rect.y,
|
|
1776
|
-
w: width,
|
|
1777
|
-
h: height,
|
|
1816
|
+
w: placement.width,
|
|
1817
|
+
h: placement.height,
|
|
1778
1818
|
protocol,
|
|
1779
|
-
sequence,
|
|
1780
|
-
resizeSequence,
|
|
1781
|
-
clearSequence,
|
|
1819
|
+
sequence: prepared.sequence,
|
|
1820
|
+
resizeSequence: prepared.resizeSequence,
|
|
1821
|
+
clearSequence: prepared.clearSequence,
|
|
1822
|
+
placementMoveWithoutClear: protocol === "kitty",
|
|
1782
1823
|
fallbackText: segment.alt ?? (segment.kind === "math" ? segment.raw ?? segment.tex ?? "math" : "image")
|
|
1783
1824
|
});
|
|
1784
|
-
markdownImageDebug(`queue id=${id}`, `accepted=${accepted ? "true" : "false"}`, `x=${rect.x}`, `y=${rect.y}`, `w=${width}`, `h=${height}`, `visibleW=${rect.w}`, `displayW=${segment.displayWidth ?? ""}`, `displayH=${segment.displayHeight ?? ""}`);
|
|
1785
|
-
if (accepted) rememberMarkdownImageGraphic(terminal, id, {
|
|
1825
|
+
markdownImageDebug(`queue id=${prepared.id}`, `accepted=${accepted ? "true" : "false"}`, `x=${rect.x}`, `y=${rect.y}`, `w=${placement.width}`, `h=${placement.height}`, `visibleW=${rect.w}`, `displayW=${segment.displayWidth ?? ""}`, `displayH=${segment.displayHeight ?? ""}`);
|
|
1826
|
+
if (accepted) rememberMarkdownImageGraphic(terminal, prepared.id, {
|
|
1786
1827
|
x: rect.x,
|
|
1787
1828
|
y: rect.y,
|
|
1788
|
-
w: width,
|
|
1789
|
-
h: height
|
|
1829
|
+
w: placement.width,
|
|
1830
|
+
h: placement.height
|
|
1790
1831
|
});
|
|
1791
1832
|
return accepted ? "queued" : "rejected";
|
|
1792
1833
|
}
|
|
@@ -1809,7 +1850,6 @@ function collectVisibleMarkdownImageGraphicIds(rows, options) {
|
|
|
1809
1850
|
logicalX = segmentEnd;
|
|
1810
1851
|
if (!segment.graphic) continue;
|
|
1811
1852
|
if (segmentEnd <= clipStart || segmentStart >= clipEnd) continue;
|
|
1812
|
-
if (Math.max(segmentStart, clipStart) !== segmentStart) continue;
|
|
1813
1853
|
const height = Math.max(1, Math.floor(segment.graphic.displayHeight ?? 1));
|
|
1814
1854
|
if (rowIndex + height <= firstRow || rowIndex >= lastRow) continue;
|
|
1815
1855
|
const rect = {
|
|
@@ -1824,6 +1864,67 @@ function collectVisibleMarkdownImageGraphicIds(rows, options) {
|
|
|
1824
1864
|
}
|
|
1825
1865
|
return keepIds;
|
|
1826
1866
|
}
|
|
1867
|
+
function queueClippedVisibleMarkdownImageGraphics(terminal, rows, options) {
|
|
1868
|
+
const queuedIds = new Set();
|
|
1869
|
+
const output = getTerminalGraphicsOutput(terminal);
|
|
1870
|
+
if (options.w <= 0 || options.h <= 0 || !output?.capabilities.supported || output.capabilities.preferredProtocol !== "kitty") return queuedIds;
|
|
1871
|
+
const clipStart = Math.max(0, Math.floor(options.clipStart));
|
|
1872
|
+
const firstRow = Math.min(rows.length, Math.max(0, Math.floor(options.rowOffset)));
|
|
1873
|
+
const lastRow = Math.min(rows.length, firstRow + Math.max(0, Math.floor(options.h)));
|
|
1874
|
+
let scanStart = firstRow;
|
|
1875
|
+
while (scanStart > 0 && (rows[scanStart]?.segments.length ?? 0) === 0) scanStart--;
|
|
1876
|
+
for (let rowIndex = scanStart; rowIndex < lastRow; rowIndex++) {
|
|
1877
|
+
const row = rows[rowIndex];
|
|
1878
|
+
if (!row) continue;
|
|
1879
|
+
let logicalX = 0;
|
|
1880
|
+
for (const [segmentIndex, segment] of row.segments.entries()) {
|
|
1881
|
+
const segmentStart = logicalX;
|
|
1882
|
+
logicalX += segment.cells;
|
|
1883
|
+
if (!segment.graphic?.base64) continue;
|
|
1884
|
+
const fullWidth = Math.max(1, Math.floor(segment.graphic.displayWidth ?? segment.cells));
|
|
1885
|
+
const fullHeight = Math.max(1, Math.floor(segment.graphic.displayHeight ?? 1));
|
|
1886
|
+
const fullRect = {
|
|
1887
|
+
x: options.x + segmentStart - clipStart,
|
|
1888
|
+
y: options.y + rowIndex - firstRow,
|
|
1889
|
+
w: fullWidth,
|
|
1890
|
+
h: fullHeight
|
|
1891
|
+
};
|
|
1892
|
+
const visibleRect = {
|
|
1893
|
+
x: Math.max(options.x, fullRect.x),
|
|
1894
|
+
y: Math.max(options.y, fullRect.y),
|
|
1895
|
+
w: Math.min(options.x + options.w, fullRect.x + fullRect.w) - Math.max(options.x, fullRect.x),
|
|
1896
|
+
h: Math.min(options.y + options.h, fullRect.y + fullRect.h) - Math.max(options.y, fullRect.y)
|
|
1897
|
+
};
|
|
1898
|
+
if (visibleRect.w <= 0 || visibleRect.h <= 0) continue;
|
|
1899
|
+
if (visibleRect.x === fullRect.x && visibleRect.y === fullRect.y && visibleRect.w === fullRect.w && visibleRect.h === fullRect.h) continue;
|
|
1900
|
+
if (options.isGraphicCovered?.(visibleRect)) continue;
|
|
1901
|
+
const naturalWidth = Math.floor(segment.graphic.naturalWidth ?? 0);
|
|
1902
|
+
const naturalHeight = Math.floor(segment.graphic.naturalHeight ?? 0);
|
|
1903
|
+
if (naturalWidth <= 0 || naturalHeight <= 0) continue;
|
|
1904
|
+
const offsetX = visibleRect.x - fullRect.x;
|
|
1905
|
+
const offsetY = visibleRect.y - fullRect.y;
|
|
1906
|
+
const sourceX = Math.floor(offsetX * naturalWidth / fullWidth);
|
|
1907
|
+
const sourceY = Math.floor(offsetY * naturalHeight / fullHeight);
|
|
1908
|
+
const sourceRight = Math.max(sourceX + 1, Math.min(naturalWidth, Math.ceil((offsetX + visibleRect.w) * naturalWidth / fullWidth)));
|
|
1909
|
+
const sourceBottom = Math.max(sourceY + 1, Math.min(naturalHeight, Math.ceil((offsetY + visibleRect.h) * naturalHeight / fullHeight)));
|
|
1910
|
+
const identity = `${row.key}:${segmentIndex}`;
|
|
1911
|
+
const result = queueMarkdownImageGraphic(terminal, segment.graphic, identity, {
|
|
1912
|
+
x: visibleRect.x,
|
|
1913
|
+
y: visibleRect.y,
|
|
1914
|
+
w: visibleRect.w
|
|
1915
|
+
}, {
|
|
1916
|
+
width: visibleRect.w,
|
|
1917
|
+
height: visibleRect.h,
|
|
1918
|
+
sourceX,
|
|
1919
|
+
sourceY,
|
|
1920
|
+
sourceWidth: sourceRight - sourceX,
|
|
1921
|
+
sourceHeight: sourceBottom - sourceY
|
|
1922
|
+
});
|
|
1923
|
+
if (result === "queued") queuedIds.add(markdownImageGraphicId(segment.graphic, identity));
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
return queuedIds;
|
|
1927
|
+
}
|
|
1827
1928
|
function paintMarkdownVisualRow(terminal, row, options) {
|
|
1828
1929
|
const clipStart = Math.max(0, Math.floor(options.clipStart ?? 0));
|
|
1829
1930
|
const clipEnd = clipStart + options.w;
|
|
@@ -1874,7 +1975,8 @@ function paintMarkdownVisualRow(terminal, row, options) {
|
|
|
1874
1975
|
h: Math.max(1, Math.floor(segment.graphic.displayHeight ?? 1))
|
|
1875
1976
|
};
|
|
1876
1977
|
const graphicCovered = options.isGraphicCovered?.(graphicRect) === true;
|
|
1877
|
-
const
|
|
1978
|
+
const graphicId = markdownImageGraphicId(segment.graphic, `${row.key}:${segmentIndex}`);
|
|
1979
|
+
const queueResult = options.prequeuedGraphicIds?.has(graphicId) === true ? "queued" : !graphicCovered && visibleStart === segmentStart && visibleCells > 0 && queueMarkdownImageGraphic(terminal, segment.graphic, `${row.key}:${segmentIndex}`, {
|
|
1878
1980
|
x: cellX,
|
|
1879
1981
|
y: options.y,
|
|
1880
1982
|
w: visibleCells
|
|
@@ -1882,7 +1984,7 @@ function paintMarkdownVisualRow(terminal, row, options) {
|
|
|
1882
1984
|
const graphicAvailable = queueResult || canAttemptMarkdownImageGraphic(terminal, segment.graphic);
|
|
1883
1985
|
const queuedGraphic = queueResult === "queued";
|
|
1884
1986
|
const suppressFallback = queuedGraphic || queueResult === "rejected" || graphicAvailable === true;
|
|
1885
|
-
if (queuedGraphic) queuedGraphics.add(
|
|
1987
|
+
if (queuedGraphic) queuedGraphics.add(graphicId);
|
|
1886
1988
|
terminal.write(suppressFallback ? spaces(visibleCells) : sliceByCellsRange(segment.fallbackText ?? segment.graphic.alt ?? (segment.graphic.kind === "math" ? segment.graphic.raw ?? segment.graphic.tex ?? "math" : "image"), 0, visibleCells) || spaces(visibleCells), {
|
|
1887
1989
|
x: cellX,
|
|
1888
1990
|
y: options.y,
|
|
@@ -1956,13 +2058,19 @@ function markdownStyleSignature(style) {
|
|
|
1956
2058
|
style.href ?? ""
|
|
1957
2059
|
].join("");
|
|
1958
2060
|
}
|
|
2061
|
+
const markdownRowSignatureCache = new WeakMap();
|
|
2062
|
+
const markdownRowGraphicSignatureCache = new WeakMap();
|
|
1959
2063
|
function markdownRowSignature(row) {
|
|
1960
2064
|
if (!row) return "";
|
|
1961
|
-
|
|
2065
|
+
const cached = markdownRowSignatureCache.get(row);
|
|
2066
|
+
if (cached != null) return cached;
|
|
2067
|
+
const signature = [
|
|
1962
2068
|
row.key,
|
|
1963
2069
|
row.plainText,
|
|
1964
2070
|
row.segments.map((segment) => `${segment.text}\u0001${segment.cells}\u0001${markdownStyleSignature(segment.style)}\u0001${segment.graphic?.src ?? ""}\u0001${segment.graphic?.base64 ?? ""}\u0001${segment.fallbackText ?? ""}`).join("")
|
|
1965
2071
|
].join("");
|
|
2072
|
+
markdownRowSignatureCache.set(row, signature);
|
|
2073
|
+
return signature;
|
|
1966
2074
|
}
|
|
1967
2075
|
function getWheelScrollInput(e) {
|
|
1968
2076
|
const deltaY = Number(e.deltaY ?? 0);
|
|
@@ -1986,7 +2094,11 @@ function getWheelScrollInput(e) {
|
|
|
1986
2094
|
}
|
|
1987
2095
|
function rowGraphicSignature(row) {
|
|
1988
2096
|
if (!row) return "";
|
|
1989
|
-
|
|
2097
|
+
const cached = markdownRowGraphicSignatureCache.get(row);
|
|
2098
|
+
if (cached != null) return cached;
|
|
2099
|
+
const signature = row.segments.filter((segment) => segment.graphic).map((segment) => `${segment.graphic.kind}\u0001${segment.graphic.src}\u0001${segment.graphic.base64 ?? ""}`).join("");
|
|
2100
|
+
markdownRowGraphicSignatureCache.set(row, signature);
|
|
2101
|
+
return signature;
|
|
1990
2102
|
}
|
|
1991
2103
|
const TVirtualMarkdown = defineComponent({
|
|
1992
2104
|
name: "TVirtualMarkdown",
|
|
@@ -2118,6 +2230,10 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2118
2230
|
imageOcclusionRects: {
|
|
2119
2231
|
type: Array,
|
|
2120
2232
|
default: void 0
|
|
2233
|
+
},
|
|
2234
|
+
rowScrollMode: {
|
|
2235
|
+
type: String,
|
|
2236
|
+
default: "off"
|
|
2121
2237
|
}
|
|
2122
2238
|
},
|
|
2123
2239
|
emits: {
|
|
@@ -2132,10 +2248,11 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2132
2248
|
},
|
|
2133
2249
|
setup(props, { emit }) {
|
|
2134
2250
|
const instance = getCurrentInstance();
|
|
2135
|
-
const { terminal, defaultStyle, events, scheduler, selection, widthProvider } = useTerminal();
|
|
2251
|
+
const { terminal, defaultStyle, events, scheduler, selection, widthProvider, render, rendererCapabilities } = useTerminal();
|
|
2136
2252
|
const layout = useLayout();
|
|
2137
2253
|
const { visible, rootProps } = useVisibility();
|
|
2138
2254
|
const parentEventZ = inject(EventZIndexContextKey, computed(() => 0));
|
|
2255
|
+
const plane = inject(RenderPlaneContextKey, ref("default"));
|
|
2139
2256
|
const eventZ = computed(() => (parentEventZ.value ?? 0) + (props.zIndex ?? 0));
|
|
2140
2257
|
const internalScrollTop = ref(0);
|
|
2141
2258
|
const documentVersion = ref(0);
|
|
@@ -2146,6 +2263,8 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2146
2263
|
let rebuildVersion = 0;
|
|
2147
2264
|
let layoutCache;
|
|
2148
2265
|
let alive = true;
|
|
2266
|
+
let dirtyRowsHint;
|
|
2267
|
+
let renderNodeId = null;
|
|
2149
2268
|
const parser = shallowRef(markRaw(createTuiMarkdownParser({
|
|
2150
2269
|
streaming: props.streaming,
|
|
2151
2270
|
customHtmlTags: props.customHtmlTags
|
|
@@ -2225,6 +2344,13 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2225
2344
|
const nextVisibleGraphics = visibleRowGraphics(nextRows, nextScrollTop);
|
|
2226
2345
|
const visibleChanged = prevVisibleRows.length !== nextVisibleRows.length || prevVisibleRows.some((row, index) => row !== nextVisibleRows[index]) || prevVisibleGraphics.some((row, index) => row !== nextVisibleGraphics[index]);
|
|
2227
2346
|
if (!builtOnce || prevScrollTop !== nextScrollTop || visibleChanged) {
|
|
2347
|
+
if (visibleChanged && prevScrollTop === nextScrollTop && prevVisibleGraphics.every((signature) => !signature) && nextVisibleGraphics.every((signature) => !signature)) {
|
|
2348
|
+
const rect = normalizedRect();
|
|
2349
|
+
const changedRows = [];
|
|
2350
|
+
const count = Math.max(prevVisibleRows.length, nextVisibleRows.length);
|
|
2351
|
+
for (let index = 0; index < count; index++) if (prevVisibleRows[index] !== nextVisibleRows[index]) changedRows.push(rect.y + index);
|
|
2352
|
+
markRowsDirty(changedRows);
|
|
2353
|
+
} else markRowsDirty(viewportRows());
|
|
2228
2354
|
documentVersion.value++;
|
|
2229
2355
|
selection.refresh();
|
|
2230
2356
|
}
|
|
@@ -2301,6 +2427,52 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2301
2427
|
for (let index = start; index < end; index++) out.push(rowGraphicSignature(sourceRows[index]));
|
|
2302
2428
|
return out;
|
|
2303
2429
|
}
|
|
2430
|
+
function viewportRows() {
|
|
2431
|
+
const rect = normalizedRect();
|
|
2432
|
+
const result = [];
|
|
2433
|
+
for (let y = rect.y; y < rect.y + rect.h; y++) result.push(y);
|
|
2434
|
+
return result;
|
|
2435
|
+
}
|
|
2436
|
+
function exposedRowsForDelta(y, height, delta) {
|
|
2437
|
+
const result = [];
|
|
2438
|
+
if (delta > 0) for (let offset = height - delta; offset < height; offset++) result.push(y + offset);
|
|
2439
|
+
else for (let offset = 0; offset < -delta; offset++) result.push(y + offset);
|
|
2440
|
+
return result;
|
|
2441
|
+
}
|
|
2442
|
+
function markRowsDirty(nextRows) {
|
|
2443
|
+
const rows$1 = new Set(dirtyRowsHint);
|
|
2444
|
+
for (const y of nextRows) rows$1.add(y);
|
|
2445
|
+
dirtyRowsHint = Array.from(rows$1).sort((a, b) => a - b);
|
|
2446
|
+
if (renderNodeId) render.markDirtyRows(renderNodeId, dirtyRowsHint);
|
|
2447
|
+
}
|
|
2448
|
+
function visibleGraphicsAt(scrollTop) {
|
|
2449
|
+
const rect = normalizedRect();
|
|
2450
|
+
const { x: clipX, y: clipY } = clipOffsets();
|
|
2451
|
+
return collectVisibleMarkdownImageGraphicIds(rows.value, {
|
|
2452
|
+
x: rect.x,
|
|
2453
|
+
y: rect.y,
|
|
2454
|
+
w: rect.w,
|
|
2455
|
+
h: rect.h,
|
|
2456
|
+
rowOffset: scrollTop + clipY,
|
|
2457
|
+
clipStart: clipX
|
|
2458
|
+
}).size > 0;
|
|
2459
|
+
}
|
|
2460
|
+
function isClipped() {
|
|
2461
|
+
const rect = normalizedRect();
|
|
2462
|
+
const full = normalizedFullRect();
|
|
2463
|
+
return rect.x !== full.x || rect.y !== full.y || rect.w !== full.w || rect.h !== full.h;
|
|
2464
|
+
}
|
|
2465
|
+
function markScrollDamage(prevTop, nextTop) {
|
|
2466
|
+
const rect = normalizedRect();
|
|
2467
|
+
const delta = nextTop - prevTop;
|
|
2468
|
+
if (rect.h <= 0 || !delta) return;
|
|
2469
|
+
const size = terminal.size();
|
|
2470
|
+
const canShiftRows = props.rowScrollMode === "unsafe-full-row" && rendererCapabilities.value.scrollOperations && rect.x === 0 && rect.w >= size.cols && rect.y >= 0 && rect.y + rect.h <= size.rows && !isClipped() && Math.abs(delta) < rect.h && !dirtyRowsHint?.length && !visibleGraphicsAt(prevTop);
|
|
2471
|
+
if (canShiftRows) {
|
|
2472
|
+
render.unsafeScrollPlaneRows(plane.value, rect.y, rect.y + rect.h, delta);
|
|
2473
|
+
markRowsDirty(exposedRowsForDelta(rect.y, rect.h, delta));
|
|
2474
|
+
} else markRowsDirty(viewportRows());
|
|
2475
|
+
}
|
|
2304
2476
|
function hasControlledScrollTop() {
|
|
2305
2477
|
return Object.prototype.hasOwnProperty.call(instance?.vnode.props ?? {}, "scrollTop");
|
|
2306
2478
|
}
|
|
@@ -2308,7 +2480,10 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2308
2480
|
const desired = Math.floor(Number(next) || 0);
|
|
2309
2481
|
const clamped = clamp(desired, 0, maxScrollTop());
|
|
2310
2482
|
const changed = internalScrollTop.value !== clamped;
|
|
2311
|
-
if (changed)
|
|
2483
|
+
if (changed) {
|
|
2484
|
+
markScrollDamage(internalScrollTop.value, clamped);
|
|
2485
|
+
internalScrollTop.value = clamped;
|
|
2486
|
+
}
|
|
2312
2487
|
if (desired !== clamped) {
|
|
2313
2488
|
emit("update:scrollTop", clamped);
|
|
2314
2489
|
emit("scroll", clamped);
|
|
@@ -2319,7 +2494,10 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2319
2494
|
const desired = Math.floor(Number(next) || 0);
|
|
2320
2495
|
const clamped = clamp(desired, 0, maxScrollTop());
|
|
2321
2496
|
const changed = internalScrollTop.value !== clamped;
|
|
2322
|
-
if (changed)
|
|
2497
|
+
if (changed) {
|
|
2498
|
+
markScrollDamage(internalScrollTop.value, clamped);
|
|
2499
|
+
internalScrollTop.value = clamped;
|
|
2500
|
+
}
|
|
2323
2501
|
if (emitChange && (changed || refreshOptions?.emitClampEvenIfUnchanged && desired !== clamped)) {
|
|
2324
2502
|
emit("update:scrollTop", clamped);
|
|
2325
2503
|
emit("scroll", clamped);
|
|
@@ -2572,7 +2750,7 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2572
2750
|
unsubscribeMathImage();
|
|
2573
2751
|
clearMarkdownImageGraphics(terminal, fullRect.value);
|
|
2574
2752
|
});
|
|
2575
|
-
useRenderNode(() => ({
|
|
2753
|
+
const renderNode = useRenderNode(() => ({
|
|
2576
2754
|
zIndex: props.zIndex,
|
|
2577
2755
|
rect: visible.value ? normalizedRect() : {
|
|
2578
2756
|
x: 0,
|
|
@@ -2580,6 +2758,7 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2580
2758
|
w: 0,
|
|
2581
2759
|
h: 0
|
|
2582
2760
|
},
|
|
2761
|
+
dirtyRowsHint,
|
|
2583
2762
|
deps: [
|
|
2584
2763
|
visible.value,
|
|
2585
2764
|
absRect.value,
|
|
@@ -2592,6 +2771,7 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2592
2771
|
props.imageOcclusionRects
|
|
2593
2772
|
],
|
|
2594
2773
|
paint: (dirtyRows) => {
|
|
2774
|
+
dirtyRowsHint = void 0;
|
|
2595
2775
|
withTextWidthProvider(widthProvider, () => {
|
|
2596
2776
|
if (!visible.value) return;
|
|
2597
2777
|
const r = normalizedRect();
|
|
@@ -2601,6 +2781,15 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2601
2781
|
const isGraphicCovered = (rect) => {
|
|
2602
2782
|
return props.imageOcclusionRects?.some((item) => intersectRect(rect, item)) === true;
|
|
2603
2783
|
};
|
|
2784
|
+
const prequeuedGraphicIds = queueClippedVisibleMarkdownImageGraphics(terminal, rows.value, {
|
|
2785
|
+
x: r.x,
|
|
2786
|
+
y: r.y,
|
|
2787
|
+
w: r.w,
|
|
2788
|
+
h: r.h,
|
|
2789
|
+
rowOffset: internalScrollTop.value + clipY,
|
|
2790
|
+
clipStart: clipX,
|
|
2791
|
+
isGraphicCovered
|
|
2792
|
+
});
|
|
2604
2793
|
const keepGraphicIds = collectVisibleMarkdownImageGraphicIds(rows.value, {
|
|
2605
2794
|
x: r.x,
|
|
2606
2795
|
y: r.y,
|
|
@@ -2621,6 +2810,7 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2621
2810
|
baseStyle,
|
|
2622
2811
|
clear: true,
|
|
2623
2812
|
keepGraphicIds,
|
|
2813
|
+
prequeuedGraphicIds,
|
|
2624
2814
|
isGraphicCovered
|
|
2625
2815
|
});
|
|
2626
2816
|
};
|
|
@@ -2632,6 +2822,9 @@ const TVirtualMarkdown = defineComponent({
|
|
|
2632
2822
|
});
|
|
2633
2823
|
}
|
|
2634
2824
|
}));
|
|
2825
|
+
watchEffect(() => {
|
|
2826
|
+
renderNodeId = renderNode.id.value;
|
|
2827
|
+
});
|
|
2635
2828
|
return () => h("span", rootProps);
|
|
2636
2829
|
}
|
|
2637
2830
|
});
|