markstream-svelte 0.0.1-beta.1
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 +77 -0
- package/dist/components/AdmonitionNode.svelte +8 -0
- package/dist/components/AdmonitionNode.svelte.d.ts +23 -0
- package/dist/components/AdmonitionNode.svelte.d.ts.map +1 -0
- package/dist/components/BlockquoteNode.svelte +10 -0
- package/dist/components/BlockquoteNode.svelte.d.ts +24 -0
- package/dist/components/BlockquoteNode.svelte.d.ts.map +1 -0
- package/dist/components/CheckboxNode.svelte +5 -0
- package/dist/components/CheckboxNode.svelte.d.ts +22 -0
- package/dist/components/CheckboxNode.svelte.d.ts.map +1 -0
- package/dist/components/CodeBlockNode.svelte +944 -0
- package/dist/components/CodeBlockNode.svelte.d.ts +43 -0
- package/dist/components/CodeBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/D2BlockNode.svelte +272 -0
- package/dist/components/D2BlockNode.svelte.d.ts +33 -0
- package/dist/components/D2BlockNode.svelte.d.ts.map +1 -0
- package/dist/components/DefinitionListNode.svelte +8 -0
- package/dist/components/DefinitionListNode.svelte.d.ts +23 -0
- package/dist/components/DefinitionListNode.svelte.d.ts.map +1 -0
- package/dist/components/EmojiNode.svelte +7 -0
- package/dist/components/EmojiNode.svelte.d.ts +22 -0
- package/dist/components/EmojiNode.svelte.d.ts.map +1 -0
- package/dist/components/EmphasisNode.svelte +8 -0
- package/dist/components/EmphasisNode.svelte.d.ts +24 -0
- package/dist/components/EmphasisNode.svelte.d.ts.map +1 -0
- package/dist/components/FallbackComponent.svelte +8 -0
- package/dist/components/FallbackComponent.svelte.d.ts +23 -0
- package/dist/components/FallbackComponent.svelte.d.ts.map +1 -0
- package/dist/components/FootnoteAnchorNode.svelte +21 -0
- package/dist/components/FootnoteAnchorNode.svelte.d.ts +22 -0
- package/dist/components/FootnoteAnchorNode.svelte.d.ts.map +1 -0
- package/dist/components/FootnoteNode.svelte +19 -0
- package/dist/components/FootnoteNode.svelte.d.ts +24 -0
- package/dist/components/FootnoteNode.svelte.d.ts.map +1 -0
- package/dist/components/FootnoteReferenceNode.svelte +26 -0
- package/dist/components/FootnoteReferenceNode.svelte.d.ts +22 -0
- package/dist/components/FootnoteReferenceNode.svelte.d.ts.map +1 -0
- package/dist/components/HardBreakNode.svelte +1 -0
- package/dist/components/HardBreakNode.svelte.d.ts +27 -0
- package/dist/components/HardBreakNode.svelte.d.ts.map +1 -0
- package/dist/components/HeadingNode.svelte +15 -0
- package/dist/components/HeadingNode.svelte.d.ts +24 -0
- package/dist/components/HeadingNode.svelte.d.ts.map +1 -0
- package/dist/components/HighlightNode.svelte +8 -0
- package/dist/components/HighlightNode.svelte.d.ts +24 -0
- package/dist/components/HighlightNode.svelte.d.ts.map +1 -0
- package/dist/components/HtmlBlockNode.svelte +8 -0
- package/dist/components/HtmlBlockNode.svelte.d.ts +23 -0
- package/dist/components/HtmlBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/HtmlInlineNode.svelte +8 -0
- package/dist/components/HtmlInlineNode.svelte.d.ts +23 -0
- package/dist/components/HtmlInlineNode.svelte.d.ts.map +1 -0
- package/dist/components/HtmlPreviewFrame.svelte +13 -0
- package/dist/components/HtmlPreviewFrame.svelte.d.ts +26 -0
- package/dist/components/HtmlPreviewFrame.svelte.d.ts.map +1 -0
- package/dist/components/ImageNode.svelte +86 -0
- package/dist/components/ImageNode.svelte.d.ts +25 -0
- package/dist/components/ImageNode.svelte.d.ts.map +1 -0
- package/dist/components/InfographicBlockNode.svelte +429 -0
- package/dist/components/InfographicBlockNode.svelte.d.ts +34 -0
- package/dist/components/InfographicBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/InlineCodeNode.svelte +7 -0
- package/dist/components/InlineCodeNode.svelte.d.ts +22 -0
- package/dist/components/InlineCodeNode.svelte.d.ts.map +1 -0
- package/dist/components/InlineWrapNode.svelte +10 -0
- package/dist/components/InlineWrapNode.svelte.d.ts +25 -0
- package/dist/components/InlineWrapNode.svelte.d.ts.map +1 -0
- package/dist/components/InsertNode.svelte +8 -0
- package/dist/components/InsertNode.svelte.d.ts +24 -0
- package/dist/components/InsertNode.svelte.d.ts.map +1 -0
- package/dist/components/LinkNode.svelte +41 -0
- package/dist/components/LinkNode.svelte.d.ts +25 -0
- package/dist/components/LinkNode.svelte.d.ts.map +1 -0
- package/dist/components/ListItemNode.svelte +9 -0
- package/dist/components/ListItemNode.svelte.d.ts +24 -0
- package/dist/components/ListItemNode.svelte.d.ts.map +1 -0
- package/dist/components/ListNode.svelte +16 -0
- package/dist/components/ListNode.svelte.d.ts +24 -0
- package/dist/components/ListNode.svelte.d.ts.map +1 -0
- package/dist/components/MarkdownCodeBlockNode.svelte +7 -0
- package/dist/components/MarkdownCodeBlockNode.svelte.d.ts +23 -0
- package/dist/components/MarkdownCodeBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/MathBlockNode.svelte +96 -0
- package/dist/components/MathBlockNode.svelte.d.ts +22 -0
- package/dist/components/MathBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/MathInlineNode.svelte +103 -0
- package/dist/components/MathInlineNode.svelte.d.ts +22 -0
- package/dist/components/MathInlineNode.svelte.d.ts.map +1 -0
- package/dist/components/MermaidBlockNode.svelte +557 -0
- package/dist/components/MermaidBlockNode.svelte.d.ts +40 -0
- package/dist/components/MermaidBlockNode.svelte.d.ts.map +1 -0
- package/dist/components/NodeOutlet.svelte +192 -0
- package/dist/components/NodeOutlet.svelte.d.ts +24 -0
- package/dist/components/NodeOutlet.svelte.d.ts.map +1 -0
- package/dist/components/NodeRenderer.svelte +349 -0
- package/dist/components/NodeRenderer.svelte.d.ts +64 -0
- package/dist/components/NodeRenderer.svelte.d.ts.map +1 -0
- package/dist/components/ParagraphNode.svelte +21 -0
- package/dist/components/ParagraphNode.svelte.d.ts +24 -0
- package/dist/components/ParagraphNode.svelte.d.ts.map +1 -0
- package/dist/components/PreCodeNode.svelte +13 -0
- package/dist/components/PreCodeNode.svelte.d.ts +22 -0
- package/dist/components/PreCodeNode.svelte.d.ts.map +1 -0
- package/dist/components/ReferenceNode.svelte +8 -0
- package/dist/components/ReferenceNode.svelte.d.ts +23 -0
- package/dist/components/ReferenceNode.svelte.d.ts.map +1 -0
- package/dist/components/RenderChildren.svelte +12 -0
- package/dist/components/RenderChildren.svelte.d.ts +24 -0
- package/dist/components/RenderChildren.svelte.d.ts.map +1 -0
- package/dist/components/StrikethroughNode.svelte +8 -0
- package/dist/components/StrikethroughNode.svelte.d.ts +24 -0
- package/dist/components/StrikethroughNode.svelte.d.ts.map +1 -0
- package/dist/components/StrongNode.svelte +8 -0
- package/dist/components/StrongNode.svelte.d.ts +24 -0
- package/dist/components/StrongNode.svelte.d.ts.map +1 -0
- package/dist/components/SubscriptNode.svelte +8 -0
- package/dist/components/SubscriptNode.svelte.d.ts +24 -0
- package/dist/components/SubscriptNode.svelte.d.ts.map +1 -0
- package/dist/components/SuperscriptNode.svelte +8 -0
- package/dist/components/SuperscriptNode.svelte.d.ts +24 -0
- package/dist/components/SuperscriptNode.svelte.d.ts.map +1 -0
- package/dist/components/TableNode.svelte +8 -0
- package/dist/components/TableNode.svelte.d.ts +23 -0
- package/dist/components/TableNode.svelte.d.ts.map +1 -0
- package/dist/components/TextNode.svelte +37 -0
- package/dist/components/TextNode.svelte.d.ts +25 -0
- package/dist/components/TextNode.svelte.d.ts.map +1 -0
- package/dist/components/ThematicBreakNode.svelte +1 -0
- package/dist/components/ThematicBreakNode.svelte.d.ts +27 -0
- package/dist/components/ThematicBreakNode.svelte.d.ts.map +1 -0
- package/dist/components/Tooltip.svelte +4 -0
- package/dist/components/Tooltip.svelte.d.ts +21 -0
- package/dist/components/Tooltip.svelte.d.ts.map +1 -0
- package/dist/components/VmrContainerNode.svelte +8 -0
- package/dist/components/VmrContainerNode.svelte.d.ts +23 -0
- package/dist/components/VmrContainerNode.svelte.d.ts.map +1 -0
- package/dist/components/shared/diagram-height.d.ts +10 -0
- package/dist/components/shared/diagram-height.d.ts.map +1 -0
- package/dist/components/shared/diagram-height.js +52 -0
- package/dist/components/shared/node-helpers.d.ts +108 -0
- package/dist/components/shared/node-helpers.d.ts.map +1 -0
- package/dist/components/shared/node-helpers.js +220 -0
- package/dist/components/shared/node-outlet-helpers.d.ts +9 -0
- package/dist/components/shared/node-outlet-helpers.d.ts.map +1 -0
- package/dist/components/shared/node-outlet-helpers.js +92 -0
- package/dist/components/shared/render-window.d.ts +19 -0
- package/dist/components/shared/render-window.d.ts.map +1 -0
- package/dist/components/shared/render-window.js +63 -0
- package/dist/components/shared/renderNodeHtml.d.ts +4 -0
- package/dist/components/shared/renderNodeHtml.d.ts.map +1 -0
- package/dist/components/shared/renderNodeHtml.js +19 -0
- package/dist/components/shared/rich-block-helpers.d.ts +7 -0
- package/dist/components/shared/rich-block-helpers.d.ts.map +1 -0
- package/dist/components/shared/rich-block-helpers.js +76 -0
- package/dist/customComponents.d.ts +10 -0
- package/dist/customComponents.d.ts.map +1 -0
- package/dist/customComponents.js +66 -0
- package/dist/enhanceRenderedHtml.d.ts +21 -0
- package/dist/enhanceRenderedHtml.d.ts.map +1 -0
- package/dist/enhanceRenderedHtml.js +768 -0
- package/dist/hydrateCustomTagContent.d.ts +3 -0
- package/dist/hydrateCustomTagContent.d.ts.map +1 -0
- package/dist/hydrateCustomTagContent.js +130 -0
- package/dist/i18n/useSafeI18n.d.ts +5 -0
- package/dist/i18n/useSafeI18n.d.ts.map +1 -0
- package/dist/i18n/useSafeI18n.js +42 -0
- package/dist/index.css +2009 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.px.css +2009 -0
- package/dist/index.tailwind.css +2009 -0
- package/dist/optional/d2.d.ts +7 -0
- package/dist/optional/d2.d.ts.map +1 -0
- package/dist/optional/d2.js +67 -0
- package/dist/optional/infographic.d.ts +2 -0
- package/dist/optional/infographic.d.ts.map +1 -0
- package/dist/optional/infographic.js +29 -0
- package/dist/optional/katex.d.ts +7 -0
- package/dist/optional/katex.d.ts.map +1 -0
- package/dist/optional/katex.js +93 -0
- package/dist/optional/mermaid.d.ts +7 -0
- package/dist/optional/mermaid.d.ts.map +1 -0
- package/dist/optional/mermaid.js +171 -0
- package/dist/optional/monaco.d.ts +5 -0
- package/dist/optional/monaco.d.ts.map +1 -0
- package/dist/optional/monaco.js +70 -0
- package/dist/parseNestedMarkdownToNodes.d.ts +15 -0
- package/dist/parseNestedMarkdownToNodes.d.ts.map +1 -0
- package/dist/parseNestedMarkdownToNodes.js +66 -0
- package/dist/renderMarkdownHtml.d.ts +31 -0
- package/dist/renderMarkdownHtml.d.ts.map +1 -0
- package/dist/renderMarkdownHtml.js +465 -0
- package/dist/sanitizeHtmlContent.d.ts +3 -0
- package/dist/sanitizeHtmlContent.d.ts.map +1 -0
- package/dist/sanitizeHtmlContent.js +175 -0
- package/dist/sanitizeSvg.d.ts +3 -0
- package/dist/sanitizeSvg.d.ts.map +1 -0
- package/dist/sanitizeSvg.js +76 -0
- package/dist/tailwind-entry.d.ts +2 -0
- package/dist/tailwind-entry.d.ts.map +1 -0
- package/dist/tailwind-entry.js +1 -0
- package/dist/tooltip/singletonTooltip.d.ts +8 -0
- package/dist/tooltip/singletonTooltip.d.ts.map +1 -0
- package/dist/tooltip/singletonTooltip.js +124 -0
- package/dist/types/monaco.d.ts +66 -0
- package/dist/types/monaco.d.ts.map +1 -0
- package/dist/types/monaco.js +1 -0
- package/dist/utils/languageIcon.d.ts +8 -0
- package/dist/utils/languageIcon.d.ts.map +1 -0
- package/dist/utils/languageIcon.js +182 -0
- package/dist/utils/normalizeKaTeXRenderInput.d.ts +2 -0
- package/dist/utils/normalizeKaTeXRenderInput.d.ts.map +1 -0
- package/dist/utils/normalizeKaTeXRenderInput.js +7 -0
- package/dist/workers/katexCdnWorker.d.ts +21 -0
- package/dist/workers/katexCdnWorker.d.ts.map +1 -0
- package/dist/workers/katexCdnWorker.js +193 -0
- package/dist/workers/katexRenderer.worker.d.ts +2 -0
- package/dist/workers/katexRenderer.worker.d.ts.map +1 -0
- package/dist/workers/katexRenderer.worker.js +55 -0
- package/dist/workers/katexWorkerClient.d.ts +36 -0
- package/dist/workers/katexWorkerClient.d.ts.map +1 -0
- package/dist/workers/katexWorkerClient.js +270 -0
- package/dist/workers/mermaidCdnWorker.d.ts +16 -0
- package/dist/workers/mermaidCdnWorker.d.ts.map +1 -0
- package/dist/workers/mermaidCdnWorker.js +235 -0
- package/dist/workers/mermaidParser.worker.d.ts +2 -0
- package/dist/workers/mermaidParser.worker.d.ts.map +1 -0
- package/dist/workers/mermaidParser.worker.js +85 -0
- package/dist/workers/mermaidWorkerClient.d.ts +16 -0
- package/dist/workers/mermaidWorkerClient.d.ts.map +1 -0
- package/dist/workers/mermaidWorkerClient.js +170 -0
- package/package.json +95 -0
|
@@ -0,0 +1,944 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { CodeBlockMonacoOptions, CodeBlockMonacoTheme } from '../types/monaco'
|
|
3
|
+
import type { SvelteRenderableNode, SvelteRenderContext } from './shared/node-helpers'
|
|
4
|
+
import { onDestroy, onMount, tick } from 'svelte'
|
|
5
|
+
import { useSafeI18n } from '../i18n/useSafeI18n'
|
|
6
|
+
import { getUseMonaco } from '../optional/monaco'
|
|
7
|
+
import { hideTooltip, showTooltipForAnchor } from '../tooltip/singletonTooltip'
|
|
8
|
+
import { getLanguageIcon, isLikelyIncompleteLanguageIdentifier, languageMap, normalizeLanguageIdentifier, resolveMonacoLanguageId } from '../utils/languageIcon'
|
|
9
|
+
import HtmlPreviewFrame from './HtmlPreviewFrame.svelte'
|
|
10
|
+
import { copyTextToClipboard, resolveCssSize } from './shared/rich-block-helpers'
|
|
11
|
+
import { getString, sanitizeClassToken } from './shared/node-helpers'
|
|
12
|
+
|
|
13
|
+
export let node: SvelteRenderableNode
|
|
14
|
+
export let context: SvelteRenderContext | undefined = undefined
|
|
15
|
+
export let isDark: boolean | undefined = undefined
|
|
16
|
+
export let loading: boolean | undefined = undefined
|
|
17
|
+
export let stream: boolean | undefined = undefined
|
|
18
|
+
export let darkTheme: CodeBlockMonacoTheme | undefined = undefined
|
|
19
|
+
export let lightTheme: CodeBlockMonacoTheme | undefined = undefined
|
|
20
|
+
export let themes: CodeBlockMonacoTheme[] | undefined = undefined
|
|
21
|
+
export let monacoOptions: CodeBlockMonacoOptions | undefined = undefined
|
|
22
|
+
export let minWidth: string | number | undefined = undefined
|
|
23
|
+
export let maxWidth: string | number | undefined = undefined
|
|
24
|
+
export let isShowPreview = true
|
|
25
|
+
export let enableFontSizeControl = true
|
|
26
|
+
export let showHeader = true
|
|
27
|
+
export let showCopyButton = true
|
|
28
|
+
export let showExpandButton = true
|
|
29
|
+
export let showPreviewButton = true
|
|
30
|
+
export let showCollapseButton = true
|
|
31
|
+
export let showFontSizeButtons = true
|
|
32
|
+
export let htmlPreviewAllowScripts = false
|
|
33
|
+
export let htmlPreviewSandbox: string | undefined = undefined
|
|
34
|
+
|
|
35
|
+
const { t } = useSafeI18n()
|
|
36
|
+
const defaultDiffHideUnchangedRegions = Object.freeze({
|
|
37
|
+
enabled: true,
|
|
38
|
+
contextLineCount: 2,
|
|
39
|
+
minimumLineCount: 4,
|
|
40
|
+
revealLineCount: 5,
|
|
41
|
+
})
|
|
42
|
+
const disabledDiffHideUnchangedRegions = Object.freeze({
|
|
43
|
+
enabled: false,
|
|
44
|
+
contextLineCount: 0,
|
|
45
|
+
minimumLineCount: Number.POSITIVE_INFINITY,
|
|
46
|
+
revealLineCount: 0,
|
|
47
|
+
})
|
|
48
|
+
const streamingLanguageTokens = ['javascript', 'plaintext', 'shellscript', 'typescript']
|
|
49
|
+
|
|
50
|
+
function resolveRecoverableFallbackLanguage(error: unknown) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error ?? '')
|
|
52
|
+
const missingLanguage = message.match(/Language `([^`]+)` is not included/)?.[1]
|
|
53
|
+
return missingLanguage && isLikelyIncompleteLanguageIdentifier(missingLanguage)
|
|
54
|
+
? missingLanguage
|
|
55
|
+
: ''
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function markEditorFallback(error: unknown) {
|
|
59
|
+
const recoverableLanguage = resolveRecoverableFallbackLanguage(error)
|
|
60
|
+
if (recoverableLanguage) {
|
|
61
|
+
fallbackLanguage = recoverableLanguage
|
|
62
|
+
useFallback = false
|
|
63
|
+
queueRecoverableLanguageRetry(recoverableLanguage)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
fallbackLanguage = rawLanguage
|
|
67
|
+
useFallback = true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isStreamingLanguagePrefix(lang: string) {
|
|
71
|
+
const token = lang.trim().split(/\s+/)[0]?.split(':')[0]?.toLowerCase() || ''
|
|
72
|
+
return token.length >= 3 && streamingLanguageTokens.some(candidate => candidate !== token && candidate.startsWith(token))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function queueRecoverableLanguageRetry(recoverableLanguage: string) {
|
|
76
|
+
if (languageRetryTimer)
|
|
77
|
+
return
|
|
78
|
+
const retry = () => {
|
|
79
|
+
languageRetryTimer = null
|
|
80
|
+
if (!mounted)
|
|
81
|
+
return
|
|
82
|
+
if (
|
|
83
|
+
rawLanguage !== recoverableLanguage
|
|
84
|
+
&& !isLikelyIncompleteLanguageIdentifier(rawLanguage)
|
|
85
|
+
&& !isStreamingLanguagePrefix(rawLanguage)
|
|
86
|
+
&& !shouldDelayEditor
|
|
87
|
+
&& !shouldDeferStreamingLanguage
|
|
88
|
+
) {
|
|
89
|
+
fallbackLanguage = ''
|
|
90
|
+
void syncEditor()
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
languageRetryTimer = setTimeout(retry, 50)
|
|
94
|
+
}
|
|
95
|
+
languageRetryTimer = setTimeout(retry, 50)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
let editorHost: HTMLDivElement | null = null
|
|
99
|
+
let helpers: any = null
|
|
100
|
+
let runtimeMonacoOptions: Record<string, any> | null = null
|
|
101
|
+
let ensureMonacoPromise: Promise<void> | null = null
|
|
102
|
+
let editorReady = false
|
|
103
|
+
let useFallback = false
|
|
104
|
+
let fallbackLanguage = ''
|
|
105
|
+
let editorKind: 'single' | 'diff' | null = null
|
|
106
|
+
let createEditorPromise: Promise<void> | null = null
|
|
107
|
+
let mounted = false
|
|
108
|
+
let collapsed = false
|
|
109
|
+
let expanded = false
|
|
110
|
+
let copied = false
|
|
111
|
+
let previewOpen = false
|
|
112
|
+
let codeFontSize = 13
|
|
113
|
+
let copyTimer: ReturnType<typeof setTimeout> | null = null
|
|
114
|
+
let lifecycleId = 0
|
|
115
|
+
let heightSyncRaf: number | null = null
|
|
116
|
+
let heightSyncDisposables: Array<{ dispose?: () => void } | (() => void)> = []
|
|
117
|
+
let lastLayoutWidth: number | null = null
|
|
118
|
+
let lastLayoutHeight: number | null = null
|
|
119
|
+
let lastThemeRequest = ''
|
|
120
|
+
let languageRetryTimer: ReturnType<typeof setTimeout> | null = null
|
|
121
|
+
let loadingSettledRefreshPromise: Promise<void> | null = null
|
|
122
|
+
let loadingSettledRefreshTimer: ReturnType<typeof setTimeout> | null = null
|
|
123
|
+
let lastSettledRefreshSignature = ''
|
|
124
|
+
let tokenizeTimer: ReturnType<typeof setTimeout> | null = null
|
|
125
|
+
let tokenizeRaf: number | null = null
|
|
126
|
+
let tokenizeShouldRefreshModelValue = false
|
|
127
|
+
|
|
128
|
+
$: rawLanguage = getString((node as any)?.language).trim()
|
|
129
|
+
$: canonicalLanguage = normalizeLanguageIdentifier(rawLanguage)
|
|
130
|
+
$: monacoLanguage = resolveMonacoLanguageId(canonicalLanguage || rawLanguage || 'plaintext')
|
|
131
|
+
$: code = getResolvedCode(node)
|
|
132
|
+
$: diff = Boolean((node as any)?.diff)
|
|
133
|
+
$: originalCode = getString((node as any)?.originalCode)
|
|
134
|
+
$: updatedCode = getString((node as any)?.updatedCode)
|
|
135
|
+
$: nodeLoading = (node as any)?.loading === true
|
|
136
|
+
$: resolvedLoading = loading ?? nodeLoading
|
|
137
|
+
$: resolvedStream = stream ?? context?.codeBlockStream ?? true
|
|
138
|
+
$: resolvedIsDark = isDark ?? context?.isDark ?? false
|
|
139
|
+
$: resolvedThemes = context?.codeBlockThemes
|
|
140
|
+
$: mergedMonacoOptions = { ...(resolvedThemes?.monacoOptions || {}), ...(monacoOptions || {}) }
|
|
141
|
+
$: resolvedMonacoOptions = buildResolvedMonacoOptions()
|
|
142
|
+
$: requestedTheme = getThemeName(
|
|
143
|
+
resolvedIsDark
|
|
144
|
+
? darkTheme ?? resolvedThemes?.darkTheme
|
|
145
|
+
: lightTheme ?? resolvedThemes?.lightTheme,
|
|
146
|
+
resolvedIsDark ? 'vitesse-dark' : 'vitesse-light',
|
|
147
|
+
)
|
|
148
|
+
$: defaultCodeFontSize = Number(mergedMonacoOptions.fontSize) || 13
|
|
149
|
+
$: minWidthValue = resolveCssSize(minWidth ?? resolvedThemes?.minWidth)
|
|
150
|
+
$: maxWidthValue = resolveCssSize(maxWidth ?? resolvedThemes?.maxWidth)
|
|
151
|
+
$: containerStyle = [
|
|
152
|
+
minWidthValue ? `min-width: ${minWidthValue}` : '',
|
|
153
|
+
maxWidthValue ? `max-width: ${maxWidthValue}` : '',
|
|
154
|
+
].filter(Boolean).join('; ')
|
|
155
|
+
$: languageIcon = getLanguageIcon(canonicalLanguage || rawLanguage || 'plain')
|
|
156
|
+
$: displayLanguage = languageMap[canonicalLanguage] || (rawLanguage ? rawLanguage.toUpperCase() : languageMap[''])
|
|
157
|
+
$: isPreviewable = isShowPreview !== false && (canonicalLanguage === 'html' || canonicalLanguage === 'svg')
|
|
158
|
+
$: previewTitle = canonicalLanguage === 'svg' ? t('artifacts.svgPreviewTitle') : t('artifacts.htmlPreviewTitle')
|
|
159
|
+
$: shouldDelayEditor = resolvedStream === false && resolvedLoading
|
|
160
|
+
$: documentStreaming = context?.final === false || resolvedLoading
|
|
161
|
+
$: shouldDeferStreamingLanguage = resolvedStream !== false && documentStreaming && (isLikelyIncompleteLanguageIdentifier(rawLanguage) || isStreamingLanguagePrefix(rawLanguage))
|
|
162
|
+
$: shouldRender = !(resolvedLoading && !code.trim())
|
|
163
|
+
$: preLanguageClass = sanitizeClassToken(rawLanguage || monacoLanguage)
|
|
164
|
+
$: showPreWhileMonacoLoads = !useFallback && !shouldDelayEditor && !shouldDeferStreamingLanguage && !editorReady
|
|
165
|
+
$: showPreFallback = useFallback || shouldDelayEditor || shouldDeferStreamingLanguage || showPreWhileMonacoLoads
|
|
166
|
+
$: settledRefreshSignature = diff
|
|
167
|
+
? `${monacoLanguage}\0${originalCode}\0${updatedCode || code}`
|
|
168
|
+
: `${monacoLanguage}\0${code}`
|
|
169
|
+
$: if (useFallback && fallbackLanguage && rawLanguage !== fallbackLanguage && isLikelyIncompleteLanguageIdentifier(fallbackLanguage)) {
|
|
170
|
+
useFallback = false
|
|
171
|
+
fallbackLanguage = ''
|
|
172
|
+
}
|
|
173
|
+
$: {
|
|
174
|
+
void mounted
|
|
175
|
+
void resolvedLoading
|
|
176
|
+
void settledRefreshSignature
|
|
177
|
+
void shouldDelayEditor
|
|
178
|
+
void shouldDeferStreamingLanguage
|
|
179
|
+
if (mounted && resolvedLoading === false && !shouldDelayEditor && !shouldDeferStreamingLanguage) {
|
|
180
|
+
if (settledRefreshSignature !== lastSettledRefreshSignature) {
|
|
181
|
+
lastSettledRefreshSignature = settledRefreshSignature
|
|
182
|
+
queueLoadingSettledRefresh()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
$: {
|
|
187
|
+
void mounted
|
|
188
|
+
void editorHost
|
|
189
|
+
void shouldRender
|
|
190
|
+
void collapsed
|
|
191
|
+
void shouldDelayEditor
|
|
192
|
+
void shouldDeferStreamingLanguage
|
|
193
|
+
void diff
|
|
194
|
+
void code
|
|
195
|
+
void originalCode
|
|
196
|
+
void updatedCode
|
|
197
|
+
void monacoLanguage
|
|
198
|
+
void requestedTheme
|
|
199
|
+
void resolvedMonacoOptions
|
|
200
|
+
void codeFontSize
|
|
201
|
+
void expanded
|
|
202
|
+
if (mounted)
|
|
203
|
+
void syncEditor()
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
onMount(() => {
|
|
207
|
+
mounted = true
|
|
208
|
+
codeFontSize = defaultCodeFontSize
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
onDestroy(() => {
|
|
212
|
+
mounted = false
|
|
213
|
+
lifecycleId += 1
|
|
214
|
+
if (copyTimer)
|
|
215
|
+
clearTimeout(copyTimer)
|
|
216
|
+
if (languageRetryTimer)
|
|
217
|
+
clearTimeout(languageRetryTimer)
|
|
218
|
+
if (loadingSettledRefreshTimer)
|
|
219
|
+
clearTimeout(loadingSettledRefreshTimer)
|
|
220
|
+
cancelEditorTokenization()
|
|
221
|
+
cleanupEditor()
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
function getResolvedCode(sourceNode: SvelteRenderableNode) {
|
|
225
|
+
if ((sourceNode as any)?.diff)
|
|
226
|
+
return getString((sourceNode as any)?.updatedCode ?? (sourceNode as any)?.code)
|
|
227
|
+
return getString((sourceNode as any)?.code)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function getThemeName(theme: CodeBlockMonacoTheme | undefined, fallback: string) {
|
|
231
|
+
if (typeof theme === 'string' && theme)
|
|
232
|
+
return theme
|
|
233
|
+
if (theme && typeof theme === 'object' && typeof (theme as any).name === 'string')
|
|
234
|
+
return String((theme as any).name)
|
|
235
|
+
return fallback
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function buildThemeList() {
|
|
239
|
+
const list: CodeBlockMonacoTheme[] = ['vitesse-dark', 'vitesse-light']
|
|
240
|
+
const add = (item: CodeBlockMonacoTheme | undefined) => {
|
|
241
|
+
if (item)
|
|
242
|
+
list.push(item)
|
|
243
|
+
}
|
|
244
|
+
add(darkTheme ?? resolvedThemes?.darkTheme)
|
|
245
|
+
add(lightTheme ?? resolvedThemes?.lightTheme)
|
|
246
|
+
for (const item of resolvedThemes?.themes || [])
|
|
247
|
+
add(item)
|
|
248
|
+
for (const item of themes || [])
|
|
249
|
+
add(item)
|
|
250
|
+
return list
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function resolveDiffHideUnchangedRegionsOption(value: unknown) {
|
|
254
|
+
if (typeof value === 'boolean')
|
|
255
|
+
return value
|
|
256
|
+
if (value && typeof value === 'object') {
|
|
257
|
+
const raw = value as Record<string, unknown>
|
|
258
|
+
return {
|
|
259
|
+
...defaultDiffHideUnchangedRegions,
|
|
260
|
+
...raw,
|
|
261
|
+
enabled: raw.enabled ?? true,
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return { ...defaultDiffHideUnchangedRegions }
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function buildResolvedMonacoOptions() {
|
|
268
|
+
const raw = { ...mergedMonacoOptions } as Record<string, any>
|
|
269
|
+
const maxHeight = expanded ? 900 : (raw.MAX_HEIGHT ?? 500)
|
|
270
|
+
const baseOptions = {
|
|
271
|
+
readOnly: true,
|
|
272
|
+
minimap: { enabled: false },
|
|
273
|
+
lineNumbers: 'on',
|
|
274
|
+
wordWrap: 'on',
|
|
275
|
+
wrappingIndent: 'same',
|
|
276
|
+
revealDebounceMs: 75,
|
|
277
|
+
}
|
|
278
|
+
const finalOptions = {
|
|
279
|
+
MAX_HEIGHT: maxHeight,
|
|
280
|
+
fontSize: codeFontSize,
|
|
281
|
+
themes: buildThemeList(),
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (!diff) {
|
|
285
|
+
return {
|
|
286
|
+
...baseOptions,
|
|
287
|
+
...raw,
|
|
288
|
+
...finalOptions,
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const diffHideUnchangedRegions = raw.diffHideUnchangedRegions === undefined
|
|
293
|
+
? { ...defaultDiffHideUnchangedRegions }
|
|
294
|
+
: resolveDiffHideUnchangedRegionsOption(raw.diffHideUnchangedRegions)
|
|
295
|
+
const hideUnchangedRegions = raw.hideUnchangedRegions === undefined
|
|
296
|
+
? undefined
|
|
297
|
+
: resolveDiffHideUnchangedRegionsOption(raw.hideUnchangedRegions)
|
|
298
|
+
const streamPreviewDiff = resolvedStream !== false && resolvedLoading !== false
|
|
299
|
+
const activeDiffHideUnchangedRegions = streamPreviewDiff
|
|
300
|
+
? { ...disabledDiffHideUnchangedRegions }
|
|
301
|
+
: diffHideUnchangedRegions
|
|
302
|
+
const activeHideUnchangedRegions = streamPreviewDiff
|
|
303
|
+
? { ...disabledDiffHideUnchangedRegions }
|
|
304
|
+
: hideUnchangedRegions
|
|
305
|
+
const experimental = {
|
|
306
|
+
...((raw.experimental as Record<string, unknown> | undefined) ?? {}),
|
|
307
|
+
}
|
|
308
|
+
const diffUnchangedRegionStyle = raw.diffUnchangedRegionStyle ?? 'line-info'
|
|
309
|
+
const diffDefaults = {
|
|
310
|
+
maxComputationTime: 0,
|
|
311
|
+
diffAlgorithm: 'legacy',
|
|
312
|
+
ignoreTrimWhitespace: false,
|
|
313
|
+
renderIndicators: true,
|
|
314
|
+
diffUpdateThrottleMs: 120,
|
|
315
|
+
renderLineHighlight: 'none',
|
|
316
|
+
renderLineHighlightOnlyWhenFocus: true,
|
|
317
|
+
selectionHighlight: false,
|
|
318
|
+
occurrencesHighlight: 'off',
|
|
319
|
+
matchBrackets: 'never',
|
|
320
|
+
lineDecorationsWidth: 4,
|
|
321
|
+
lineNumbersMinChars: 2,
|
|
322
|
+
glyphMargin: false,
|
|
323
|
+
renderOverviewRuler: false,
|
|
324
|
+
overviewRulerBorder: false,
|
|
325
|
+
hideCursorInOverviewRuler: true,
|
|
326
|
+
scrollBeyondLastLine: false,
|
|
327
|
+
diffHideUnchangedRegions: activeDiffHideUnchangedRegions,
|
|
328
|
+
useInlineViewWhenSpaceIsLimited: raw.useInlineViewWhenSpaceIsLimited ?? false,
|
|
329
|
+
diffLineStyle: 'background',
|
|
330
|
+
diffAppearance: 'auto',
|
|
331
|
+
diffUnchangedRegionStyle,
|
|
332
|
+
diffHunkActionsOnHover: false,
|
|
333
|
+
experimental,
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
...baseOptions,
|
|
338
|
+
...diffDefaults,
|
|
339
|
+
...raw,
|
|
340
|
+
experimental,
|
|
341
|
+
...(activeHideUnchangedRegions === undefined ? {} : { hideUnchangedRegions: activeHideUnchangedRegions }),
|
|
342
|
+
diffHideUnchangedRegions: activeDiffHideUnchangedRegions,
|
|
343
|
+
...finalOptions,
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function syncRuntimeMonacoOptions() {
|
|
348
|
+
const nextOptions = {
|
|
349
|
+
...resolvedMonacoOptions,
|
|
350
|
+
theme: requestedTheme,
|
|
351
|
+
}
|
|
352
|
+
if (!runtimeMonacoOptions) {
|
|
353
|
+
runtimeMonacoOptions = nextOptions
|
|
354
|
+
return runtimeMonacoOptions
|
|
355
|
+
}
|
|
356
|
+
for (const key of Object.keys(runtimeMonacoOptions)) {
|
|
357
|
+
if (!(key in nextOptions))
|
|
358
|
+
delete runtimeMonacoOptions[key]
|
|
359
|
+
}
|
|
360
|
+
Object.assign(runtimeMonacoOptions, nextOptions)
|
|
361
|
+
return runtimeMonacoOptions
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async function ensureMonaco() {
|
|
365
|
+
if (helpers || useFallback || typeof window === 'undefined')
|
|
366
|
+
return
|
|
367
|
+
if (ensureMonacoPromise)
|
|
368
|
+
return ensureMonacoPromise
|
|
369
|
+
|
|
370
|
+
ensureMonacoPromise = (async () => {
|
|
371
|
+
const mod = await getUseMonaco()
|
|
372
|
+
if (!mounted)
|
|
373
|
+
return
|
|
374
|
+
if (!mod || typeof mod.useMonaco !== 'function') {
|
|
375
|
+
useFallback = true
|
|
376
|
+
return
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
helpers = mod.useMonaco(syncRuntimeMonacoOptions())
|
|
380
|
+
lastThemeRequest = requestedTheme
|
|
381
|
+
})().finally(() => {
|
|
382
|
+
ensureMonacoPromise = null
|
|
383
|
+
})
|
|
384
|
+
return ensureMonacoPromise
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function queueThemeSync() {
|
|
388
|
+
if (!helpers || !requestedTheme || requestedTheme === lastThemeRequest)
|
|
389
|
+
return
|
|
390
|
+
lastThemeRequest = requestedTheme
|
|
391
|
+
void Promise.resolve(helpers.setTheme?.(requestedTheme)).catch((error) => {
|
|
392
|
+
if (typeof console !== 'undefined')
|
|
393
|
+
console.warn('[markstream-svelte] Failed to apply Monaco theme:', error)
|
|
394
|
+
})
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
async function syncEditor() {
|
|
398
|
+
if (!mounted || !shouldRender || !editorHost || collapsed || shouldDelayEditor || shouldDeferStreamingLanguage)
|
|
399
|
+
return
|
|
400
|
+
|
|
401
|
+
await ensureMonaco()
|
|
402
|
+
if (!mounted || useFallback || !helpers)
|
|
403
|
+
return
|
|
404
|
+
syncRuntimeMonacoOptions()
|
|
405
|
+
|
|
406
|
+
const desiredKind: 'single' | 'diff' = diff ? 'diff' : 'single'
|
|
407
|
+
const hasEditorView = desiredKind === 'diff'
|
|
408
|
+
? Boolean(helpers.getDiffEditorView?.())
|
|
409
|
+
: Boolean(helpers.getEditorView?.())
|
|
410
|
+
const hasEditor = hasEditorView && hasRenderedEditorDom(desiredKind)
|
|
411
|
+
|
|
412
|
+
if (!hasEditor || editorKind !== desiredKind) {
|
|
413
|
+
await recreateEditor(desiredKind)
|
|
414
|
+
if (!mounted || useFallback || !helpers)
|
|
415
|
+
return
|
|
416
|
+
if (!hasRenderedEditorDom(desiredKind) || editorKind !== desiredKind)
|
|
417
|
+
return
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
try {
|
|
421
|
+
if (diff && typeof helpers.updateDiff === 'function')
|
|
422
|
+
await Promise.resolve(helpers.updateDiff(originalCode, updatedCode || code, monacoLanguage))
|
|
423
|
+
else if (typeof helpers.updateCode === 'function') {
|
|
424
|
+
await Promise.resolve(helpers.updateCode(code, monacoLanguage))
|
|
425
|
+
scheduleEditorTokenization()
|
|
426
|
+
}
|
|
427
|
+
queueThemeSync()
|
|
428
|
+
applyEditorOptions()
|
|
429
|
+
scheduleEditorHeightSync()
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
markEditorFallback(error)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function hasRenderedEditorDom(kind: 'single' | 'diff') {
|
|
437
|
+
if (!editorHost)
|
|
438
|
+
return false
|
|
439
|
+
return kind === 'diff'
|
|
440
|
+
? Boolean(editorHost.querySelector('.monaco-diff-editor'))
|
|
441
|
+
: Boolean(editorHost.querySelector('.monaco-editor'))
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async function recreateEditor(kind: 'single' | 'diff') {
|
|
445
|
+
if (!editorHost || !helpers || createEditorPromise)
|
|
446
|
+
return createEditorPromise
|
|
447
|
+
|
|
448
|
+
const creationId = ++lifecycleId
|
|
449
|
+
editorReady = false
|
|
450
|
+
createEditorPromise = (async () => {
|
|
451
|
+
try {
|
|
452
|
+
cleanupEditor(false)
|
|
453
|
+
if (!mounted || !editorHost || lifecycleId !== creationId)
|
|
454
|
+
return
|
|
455
|
+
editorHost.replaceChildren()
|
|
456
|
+
lastLayoutWidth = null
|
|
457
|
+
lastLayoutHeight = null
|
|
458
|
+
|
|
459
|
+
if (kind === 'diff' && typeof helpers.createDiffEditor === 'function') {
|
|
460
|
+
await helpers.createDiffEditor(editorHost, originalCode, updatedCode || code, monacoLanguage)
|
|
461
|
+
await Promise.resolve(helpers.updateDiff?.(originalCode, updatedCode || code, monacoLanguage))
|
|
462
|
+
editorKind = 'diff'
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
await helpers.createEditor(editorHost, code, monacoLanguage)
|
|
466
|
+
await Promise.resolve(helpers.updateCode?.(code, monacoLanguage))
|
|
467
|
+
editorKind = 'single'
|
|
468
|
+
}
|
|
469
|
+
applyEditorOptions()
|
|
470
|
+
editorReady = true
|
|
471
|
+
bindEditorHeightSync()
|
|
472
|
+
scheduleEditorHeightSync()
|
|
473
|
+
queueThemeSync()
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
if (mounted) {
|
|
477
|
+
markEditorFallback(error)
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
})().finally(() => {
|
|
481
|
+
createEditorPromise = null
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
return createEditorPromise
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function refreshEditorAfterLoadingSettled() {
|
|
488
|
+
if (loadingSettledRefreshPromise)
|
|
489
|
+
return loadingSettledRefreshPromise
|
|
490
|
+
|
|
491
|
+
loadingSettledRefreshPromise = (async () => {
|
|
492
|
+
await tick()
|
|
493
|
+
await nextAnimationFrame()
|
|
494
|
+
if (createEditorPromise) {
|
|
495
|
+
try {
|
|
496
|
+
await createEditorPromise
|
|
497
|
+
}
|
|
498
|
+
catch {}
|
|
499
|
+
}
|
|
500
|
+
if (!mounted || !shouldRender || !editorHost || collapsed || shouldDelayEditor || shouldDeferStreamingLanguage)
|
|
501
|
+
return
|
|
502
|
+
await ensureMonaco()
|
|
503
|
+
if (!mounted || useFallback || !helpers)
|
|
504
|
+
return
|
|
505
|
+
syncRuntimeMonacoOptions()
|
|
506
|
+
const desiredKind: 'single' | 'diff' = diff ? 'diff' : 'single'
|
|
507
|
+
if (!hasRenderedEditorDom(desiredKind) || editorKind !== desiredKind)
|
|
508
|
+
await recreateEditor(desiredKind)
|
|
509
|
+
if (!mounted || useFallback || !helpers || !hasRenderedEditorDom(desiredKind) || editorKind !== desiredKind)
|
|
510
|
+
return
|
|
511
|
+
if (diff) {
|
|
512
|
+
await Promise.resolve(helpers.updateDiff?.(originalCode, updatedCode || code, monacoLanguage))
|
|
513
|
+
helpers.refreshDiffPresentation?.()
|
|
514
|
+
applyEditorOptions()
|
|
515
|
+
scheduleEditorHeightSync()
|
|
516
|
+
return
|
|
517
|
+
}
|
|
518
|
+
await Promise.resolve(helpers.updateCode?.(code, monacoLanguage))
|
|
519
|
+
scheduleEditorTokenization(140, true)
|
|
520
|
+
applyEditorOptions()
|
|
521
|
+
scheduleEditorHeightSync()
|
|
522
|
+
})().finally(() => {
|
|
523
|
+
loadingSettledRefreshPromise = null
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
return loadingSettledRefreshPromise
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function queueLoadingSettledRefresh() {
|
|
530
|
+
if (loadingSettledRefreshTimer)
|
|
531
|
+
clearTimeout(loadingSettledRefreshTimer)
|
|
532
|
+
loadingSettledRefreshTimer = setTimeout(() => {
|
|
533
|
+
loadingSettledRefreshTimer = null
|
|
534
|
+
void refreshEditorAfterLoadingSettled()
|
|
535
|
+
}, 80)
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function nextAnimationFrame() {
|
|
539
|
+
if (typeof window === 'undefined' || typeof window.requestAnimationFrame !== 'function')
|
|
540
|
+
return Promise.resolve()
|
|
541
|
+
return new Promise<void>(resolve => window.requestAnimationFrame(() => resolve()))
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function cleanupEditor(disposeHelpers = true) {
|
|
545
|
+
clearEditorHeightSyncBindings()
|
|
546
|
+
cancelEditorHeightSync()
|
|
547
|
+
try {
|
|
548
|
+
if (disposeHelpers)
|
|
549
|
+
helpers?.cleanupEditor?.()
|
|
550
|
+
else
|
|
551
|
+
(helpers?.safeClean || helpers?.cleanupEditor)?.()
|
|
552
|
+
}
|
|
553
|
+
catch {}
|
|
554
|
+
editorKind = null
|
|
555
|
+
editorReady = false
|
|
556
|
+
lastLayoutWidth = null
|
|
557
|
+
lastLayoutHeight = null
|
|
558
|
+
if (disposeHelpers) {
|
|
559
|
+
helpers = null
|
|
560
|
+
runtimeMonacoOptions = null
|
|
561
|
+
ensureMonacoPromise = null
|
|
562
|
+
lastThemeRequest = ''
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
function applyEditorOptions() {
|
|
567
|
+
const target = diff ? helpers?.getDiffEditorView?.() : helpers?.getEditorView?.()
|
|
568
|
+
target?.updateOptions?.({ fontSize: codeFontSize, automaticLayout: false })
|
|
569
|
+
scheduleEditorHeightSync()
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function getMaxHeightValue() {
|
|
573
|
+
const raw = resolvedMonacoOptions.MAX_HEIGHT
|
|
574
|
+
if (raw === 'none' || raw == null)
|
|
575
|
+
return Number.POSITIVE_INFINITY
|
|
576
|
+
const value = typeof raw === 'number' ? raw : Number.parseFloat(String(raw))
|
|
577
|
+
return Number.isFinite(value) && value > 0 ? value : 500
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function scheduleEditorHeightSync() {
|
|
581
|
+
if (typeof window === 'undefined' || !editorHost || !editorReady)
|
|
582
|
+
return
|
|
583
|
+
if (heightSyncRaf != null)
|
|
584
|
+
return
|
|
585
|
+
heightSyncRaf = window.requestAnimationFrame(() => {
|
|
586
|
+
heightSyncRaf = null
|
|
587
|
+
window.requestAnimationFrame(() => syncEditorHostHeight())
|
|
588
|
+
})
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
function cancelEditorHeightSync() {
|
|
592
|
+
if (heightSyncRaf == null || typeof window === 'undefined')
|
|
593
|
+
return
|
|
594
|
+
window.cancelAnimationFrame(heightSyncRaf)
|
|
595
|
+
heightSyncRaf = null
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
function scheduleEditorTokenization(delay = 140, refreshModelValue = false) {
|
|
599
|
+
if (typeof window === 'undefined')
|
|
600
|
+
return
|
|
601
|
+
tokenizeShouldRefreshModelValue = tokenizeShouldRefreshModelValue || refreshModelValue
|
|
602
|
+
if (tokenizeTimer)
|
|
603
|
+
clearTimeout(tokenizeTimer)
|
|
604
|
+
tokenizeTimer = setTimeout(() => {
|
|
605
|
+
tokenizeTimer = null
|
|
606
|
+
if (tokenizeRaf != null)
|
|
607
|
+
return
|
|
608
|
+
tokenizeRaf = window.requestAnimationFrame(() => {
|
|
609
|
+
const shouldRefreshModelValue = tokenizeShouldRefreshModelValue
|
|
610
|
+
tokenizeShouldRefreshModelValue = false
|
|
611
|
+
tokenizeRaf = null
|
|
612
|
+
forceTokenizeEditorModel(shouldRefreshModelValue)
|
|
613
|
+
})
|
|
614
|
+
}, delay)
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
function cancelEditorTokenization() {
|
|
618
|
+
if (tokenizeTimer) {
|
|
619
|
+
clearTimeout(tokenizeTimer)
|
|
620
|
+
tokenizeTimer = null
|
|
621
|
+
}
|
|
622
|
+
tokenizeShouldRefreshModelValue = false
|
|
623
|
+
if (tokenizeRaf == null || typeof window === 'undefined')
|
|
624
|
+
return
|
|
625
|
+
window.cancelAnimationFrame(tokenizeRaf)
|
|
626
|
+
tokenizeRaf = null
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
function forceTokenizeEditorModel(refreshModelValue = false) {
|
|
630
|
+
try {
|
|
631
|
+
const editor = diff
|
|
632
|
+
? helpers?.getDiffEditorView?.()?.getModifiedEditor?.()
|
|
633
|
+
: helpers?.getEditorView?.()
|
|
634
|
+
const model = editor?.getModel?.()
|
|
635
|
+
const forceTokenization = model?.forceTokenization
|
|
636
|
+
if (refreshModelValue && !diff && typeof model?.setValue === 'function') {
|
|
637
|
+
const scrollTop = Number(editor?.getScrollTop?.() || 0)
|
|
638
|
+
const scrollLeft = Number(editor?.getScrollLeft?.() || 0)
|
|
639
|
+
const selection = editor?.getSelection?.()
|
|
640
|
+
model.setValue(code)
|
|
641
|
+
if (selection)
|
|
642
|
+
editor?.setSelection?.(selection)
|
|
643
|
+
if (Number.isFinite(scrollTop))
|
|
644
|
+
editor?.setScrollTop?.(scrollTop)
|
|
645
|
+
if (Number.isFinite(scrollLeft))
|
|
646
|
+
editor?.setScrollLeft?.(scrollLeft)
|
|
647
|
+
}
|
|
648
|
+
const lineCount = Number(model?.getLineCount?.() || 0)
|
|
649
|
+
if (typeof forceTokenization !== 'function' || !Number.isFinite(lineCount) || lineCount <= 0)
|
|
650
|
+
return
|
|
651
|
+
for (let line = 1; line <= lineCount; line += 1)
|
|
652
|
+
forceTokenization.call(model, line)
|
|
653
|
+
editor?.render?.(true)
|
|
654
|
+
}
|
|
655
|
+
catch {}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
function bindEditorHeightSync() {
|
|
659
|
+
clearEditorHeightSyncBindings()
|
|
660
|
+
const bind = (source: any, eventName: 'onDidContentSizeChange' | 'onDidLayoutChange') => {
|
|
661
|
+
try {
|
|
662
|
+
const subscribe = source?.[eventName]
|
|
663
|
+
if (typeof subscribe !== 'function')
|
|
664
|
+
return
|
|
665
|
+
const disposable = subscribe.call(source, () => scheduleEditorHeightSync())
|
|
666
|
+
if (disposable)
|
|
667
|
+
heightSyncDisposables.push(disposable)
|
|
668
|
+
}
|
|
669
|
+
catch {}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
if (diff) {
|
|
673
|
+
const diffEditor = helpers?.getDiffEditorView?.()
|
|
674
|
+
const originalEditor = diffEditor?.getOriginalEditor?.()
|
|
675
|
+
const modifiedEditor = diffEditor?.getModifiedEditor?.()
|
|
676
|
+
try {
|
|
677
|
+
const disposable = diffEditor?.onDidUpdateDiff?.(() => scheduleEditorHeightSync())
|
|
678
|
+
if (disposable)
|
|
679
|
+
heightSyncDisposables.push(disposable)
|
|
680
|
+
}
|
|
681
|
+
catch {}
|
|
682
|
+
bind(originalEditor, 'onDidContentSizeChange')
|
|
683
|
+
bind(modifiedEditor, 'onDidContentSizeChange')
|
|
684
|
+
bind(originalEditor, 'onDidLayoutChange')
|
|
685
|
+
bind(modifiedEditor, 'onDidLayoutChange')
|
|
686
|
+
return
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const editor = helpers?.getEditorView?.()
|
|
690
|
+
bind(editor, 'onDidContentSizeChange')
|
|
691
|
+
bind(editor, 'onDidLayoutChange')
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
function clearEditorHeightSyncBindings() {
|
|
695
|
+
for (const disposable of heightSyncDisposables) {
|
|
696
|
+
try {
|
|
697
|
+
if (typeof disposable === 'function')
|
|
698
|
+
disposable()
|
|
699
|
+
else
|
|
700
|
+
disposable?.dispose?.()
|
|
701
|
+
}
|
|
702
|
+
catch {}
|
|
703
|
+
}
|
|
704
|
+
heightSyncDisposables = []
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function syncEditorHostHeight() {
|
|
708
|
+
if (!editorHost || !helpers || !editorReady || collapsed)
|
|
709
|
+
return
|
|
710
|
+
|
|
711
|
+
const maxHeight = getMaxHeightValue()
|
|
712
|
+
const contentHeight = diff
|
|
713
|
+
? measureRenderedDiffHeight(editorHost) ?? computeEditorContentHeight()
|
|
714
|
+
: computeEditorContentHeight()
|
|
715
|
+
if (!contentHeight || contentHeight <= 0)
|
|
716
|
+
return
|
|
717
|
+
|
|
718
|
+
const minHeight = getEditorHostMinHeight()
|
|
719
|
+
const cappedHeight = expanded || !Number.isFinite(maxHeight)
|
|
720
|
+
? Math.ceil(contentHeight)
|
|
721
|
+
: Math.ceil(Math.min(contentHeight, maxHeight))
|
|
722
|
+
const nextHeight = Math.max(minHeight, cappedHeight)
|
|
723
|
+
editorHost.style.height = `${nextHeight}px`
|
|
724
|
+
editorHost.style.minHeight = `${nextHeight}px`
|
|
725
|
+
editorHost.style.maxHeight = expanded || !Number.isFinite(maxHeight) ? 'none' : `${Math.ceil(maxHeight)}px`
|
|
726
|
+
editorHost.style.overflow = diff ? 'hidden' : (contentHeight > nextHeight ? 'auto' : 'hidden')
|
|
727
|
+
layoutEditor(nextHeight)
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
function getEditorHostMinHeight() {
|
|
731
|
+
if (!editorHost || typeof window === 'undefined')
|
|
732
|
+
return 0
|
|
733
|
+
const values = [
|
|
734
|
+
window.getComputedStyle(editorHost.parentElement || editorHost).minHeight,
|
|
735
|
+
window.getComputedStyle(editorHost).minHeight,
|
|
736
|
+
]
|
|
737
|
+
for (const value of values) {
|
|
738
|
+
const parsed = Number.parseFloat(value)
|
|
739
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
740
|
+
return Math.ceil(parsed)
|
|
741
|
+
}
|
|
742
|
+
return 0
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
function layoutEditor(height: number) {
|
|
746
|
+
const width = Math.max(0, editorHost?.clientWidth || 0)
|
|
747
|
+
const roundedWidth = Math.ceil(width)
|
|
748
|
+
const roundedHeight = Math.ceil(height)
|
|
749
|
+
if (lastLayoutWidth === roundedWidth && lastLayoutHeight === roundedHeight)
|
|
750
|
+
return
|
|
751
|
+
lastLayoutWidth = roundedWidth
|
|
752
|
+
lastLayoutHeight = roundedHeight
|
|
753
|
+
try {
|
|
754
|
+
if (diff)
|
|
755
|
+
helpers?.getDiffEditorView?.()?.layout?.(width > 0 ? { width: roundedWidth, height: roundedHeight } : undefined)
|
|
756
|
+
else
|
|
757
|
+
helpers?.getEditorView?.()?.layout?.(width > 0 ? { width: roundedWidth, height: roundedHeight } : undefined)
|
|
758
|
+
}
|
|
759
|
+
catch {}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
function computeEditorContentHeight() {
|
|
763
|
+
try {
|
|
764
|
+
if (diff) {
|
|
765
|
+
const diffEditor = helpers?.getDiffEditorView?.()
|
|
766
|
+
const originalEditor = diffEditor?.getOriginalEditor?.()
|
|
767
|
+
const modifiedEditor = diffEditor?.getModifiedEditor?.()
|
|
768
|
+
const originalHeight = Number(originalEditor?.getContentHeight?.() || 0)
|
|
769
|
+
const modifiedHeight = Number(modifiedEditor?.getContentHeight?.() || 0)
|
|
770
|
+
const height = Math.max(originalHeight, modifiedHeight)
|
|
771
|
+
if (height > 0)
|
|
772
|
+
return Math.ceil(height + 1)
|
|
773
|
+
}
|
|
774
|
+
const editor = helpers?.getEditorView?.()
|
|
775
|
+
const height = Number(editor?.getContentHeight?.() || 0)
|
|
776
|
+
if (height > 0)
|
|
777
|
+
return Math.ceil(height + 1)
|
|
778
|
+
}
|
|
779
|
+
catch {}
|
|
780
|
+
return null
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
function measureRenderedDiffHeight(container: HTMLElement) {
|
|
784
|
+
if (typeof window === 'undefined')
|
|
785
|
+
return null
|
|
786
|
+
try {
|
|
787
|
+
const hostRect = container.getBoundingClientRect()
|
|
788
|
+
if (hostRect.height <= 0)
|
|
789
|
+
return null
|
|
790
|
+
|
|
791
|
+
const selectors = [
|
|
792
|
+
'.editor.original .view-lines .view-line',
|
|
793
|
+
'.editor.modified .view-lines .view-line',
|
|
794
|
+
'.editor.original .view-zones > div',
|
|
795
|
+
'.editor.modified .view-zones > div',
|
|
796
|
+
'.editor.original .margin-view-zones > div',
|
|
797
|
+
'.editor.modified .margin-view-zones > div',
|
|
798
|
+
'.editor.original .diff-hidden-lines',
|
|
799
|
+
'.editor.modified .diff-hidden-lines',
|
|
800
|
+
'.stream-monaco-diff-unchanged-bridge',
|
|
801
|
+
]
|
|
802
|
+
|
|
803
|
+
let bottom = 0
|
|
804
|
+
for (const node of Array.from(container.querySelectorAll<HTMLElement>(selectors.join(',')))) {
|
|
805
|
+
const style = window.getComputedStyle(node)
|
|
806
|
+
if (style.display === 'none' || style.visibility === 'hidden')
|
|
807
|
+
continue
|
|
808
|
+
if (Number.parseFloat(style.opacity || '1') <= 0.01)
|
|
809
|
+
continue
|
|
810
|
+
const rect = node.getBoundingClientRect()
|
|
811
|
+
if (rect.height <= 0 || rect.bottom <= hostRect.top)
|
|
812
|
+
continue
|
|
813
|
+
bottom = Math.max(bottom, rect.bottom - hostRect.top)
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (bottom > 0)
|
|
817
|
+
return Math.ceil(bottom + 1)
|
|
818
|
+
|
|
819
|
+
const diffRoot = container.querySelector<HTMLElement>('.monaco-diff-editor')
|
|
820
|
+
const diffHeight = diffRoot?.getBoundingClientRect?.().height ?? 0
|
|
821
|
+
return diffHeight > 0 ? Math.ceil(diffHeight + 1) : null
|
|
822
|
+
}
|
|
823
|
+
catch {
|
|
824
|
+
return null
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
async function copy() {
|
|
829
|
+
await copyTextToClipboard(code)
|
|
830
|
+
context?.events?.onCopy?.(code)
|
|
831
|
+
copied = true
|
|
832
|
+
if (copyTimer)
|
|
833
|
+
clearTimeout(copyTimer)
|
|
834
|
+
copyTimer = setTimeout(() => {
|
|
835
|
+
copied = false
|
|
836
|
+
}, 1000)
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
function decreaseFont() {
|
|
840
|
+
if (!enableFontSizeControl)
|
|
841
|
+
return
|
|
842
|
+
codeFontSize = Math.max(10, codeFontSize - 1)
|
|
843
|
+
applyEditorOptions()
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function resetFont() {
|
|
847
|
+
if (!enableFontSizeControl)
|
|
848
|
+
return
|
|
849
|
+
codeFontSize = defaultCodeFontSize
|
|
850
|
+
applyEditorOptions()
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
function increaseFont() {
|
|
854
|
+
if (!enableFontSizeControl)
|
|
855
|
+
return
|
|
856
|
+
codeFontSize = Math.min(24, codeFontSize + 1)
|
|
857
|
+
applyEditorOptions()
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function showButtonTooltip(event: MouseEvent | FocusEvent, text: string) {
|
|
861
|
+
const target = event.currentTarget as HTMLElement | null
|
|
862
|
+
if (!target || (target instanceof HTMLButtonElement && target.disabled))
|
|
863
|
+
return
|
|
864
|
+
showTooltipForAnchor(target, text, 'top', false, undefined, resolvedIsDark)
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
function showCopyTooltip(event: MouseEvent | FocusEvent) {
|
|
868
|
+
showButtonTooltip(event, copied ? (t('common.copied') || 'Copied') : (t('common.copy') || 'Copy'))
|
|
869
|
+
}
|
|
870
|
+
</script>
|
|
871
|
+
|
|
872
|
+
{#if shouldRender}
|
|
873
|
+
<div
|
|
874
|
+
class:is-dark={resolvedIsDark}
|
|
875
|
+
class:is-plain-text={monacoLanguage === 'plaintext'}
|
|
876
|
+
class:is-rendering={resolvedLoading}
|
|
877
|
+
class:is-diff={diff}
|
|
878
|
+
class="code-block-container"
|
|
879
|
+
data-markstream-code-block="1"
|
|
880
|
+
data-markstream-enhanced={editorReady && !useFallback ? 'true' : 'false'}
|
|
881
|
+
style={containerStyle}
|
|
882
|
+
>
|
|
883
|
+
{#if showHeader}
|
|
884
|
+
<div class="code-block-header">
|
|
885
|
+
<div class="code-block-header__meta">
|
|
886
|
+
<span class="code-block-language-icon" aria-hidden="true">{@html languageIcon}</span>
|
|
887
|
+
<span class="code-block-header__label">{diff ? `Diff / ${displayLanguage}` : displayLanguage}</span>
|
|
888
|
+
</div>
|
|
889
|
+
<div class="code-block-header__actions">
|
|
890
|
+
{#if showCopyButton}
|
|
891
|
+
<button type="button" class="code-action-btn" aria-label={copied ? t('common.copied') : t('common.copy')} onblur={() => hideTooltip()} onclick={copy} onfocus={showCopyTooltip} onmouseleave={() => hideTooltip()} onmouseenter={showCopyTooltip}>
|
|
892
|
+
{#if copied}
|
|
893
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 6L9 17l-5-5" /></svg>
|
|
894
|
+
{:else}
|
|
895
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></g></svg>
|
|
896
|
+
{/if}
|
|
897
|
+
</button>
|
|
898
|
+
{/if}
|
|
899
|
+
{#if showFontSizeButtons && enableFontSizeControl}
|
|
900
|
+
<button type="button" class="code-action-btn" aria-label={t('common.decrease')} onblur={() => hideTooltip()} onclick={decreaseFont} onfocus={(event) => showButtonTooltip(event, t('common.decrease') || 'Decrease')} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, t('common.decrease') || 'Decrease')}>
|
|
901
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14" /></svg>
|
|
902
|
+
</button>
|
|
903
|
+
<button type="button" class="code-action-btn" aria-label={t('common.reset')} onblur={() => hideTooltip()} onclick={resetFont} onfocus={(event) => showButtonTooltip(event, t('common.reset') || 'Reset')} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, t('common.reset') || 'Reset')}>
|
|
904
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12a9 9 0 1 0 9-9a9.75 9.75 0 0 0-6.74 2.74L3 8m0-5v5h5" /></svg>
|
|
905
|
+
</button>
|
|
906
|
+
<button type="button" class="code-action-btn" aria-label={t('common.increase')} onblur={() => hideTooltip()} onclick={increaseFont} onfocus={(event) => showButtonTooltip(event, t('common.increase') || 'Increase')} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, t('common.increase') || 'Increase')}>
|
|
907
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14m-7-7v14" /></svg>
|
|
908
|
+
</button>
|
|
909
|
+
{/if}
|
|
910
|
+
{#if isPreviewable && showPreviewButton}
|
|
911
|
+
<button type="button" class="code-action-btn" aria-label={t('common.preview')} onblur={() => hideTooltip()} onclick={() => (previewOpen = !previewOpen)} onfocus={(event) => showButtonTooltip(event, t('common.preview') || 'Preview')} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, t('common.preview') || 'Preview')}>
|
|
912
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" /></g></svg>
|
|
913
|
+
</button>
|
|
914
|
+
{/if}
|
|
915
|
+
{#if showExpandButton}
|
|
916
|
+
<button type="button" class="code-action-btn" aria-pressed={expanded} aria-label={expanded ? t('common.collapse') : t('common.expand')} onblur={() => hideTooltip()} onclick={() => (expanded = !expanded)} onfocus={(event) => showButtonTooltip(event, expanded ? (t('common.collapse') || 'Collapse') : (t('common.expand') || 'Expand'))} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, expanded ? (t('common.collapse') || 'Collapse') : (t('common.expand') || 'Expand'))}>
|
|
917
|
+
<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d={expanded ? 'm14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6' : 'M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6'} /></svg>
|
|
918
|
+
</button>
|
|
919
|
+
{/if}
|
|
920
|
+
{#if showCollapseButton}
|
|
921
|
+
<button type="button" class="code-action-btn" aria-pressed={collapsed} aria-label={collapsed ? t('common.expand') : t('common.collapse')} onblur={() => hideTooltip()} onclick={() => (collapsed = !collapsed)} onfocus={(event) => showButtonTooltip(event, collapsed ? (t('common.expand') || 'Expand') : (t('common.collapse') || 'Collapse'))} onmouseleave={() => hideTooltip()} onmouseenter={(event) => showButtonTooltip(event, collapsed ? (t('common.expand') || 'Expand') : (t('common.collapse') || 'Collapse'))}>
|
|
922
|
+
<svg style:rotate={collapsed ? '0deg' : '90deg'} viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 18l6-6l-6-6" /></svg>
|
|
923
|
+
</button>
|
|
924
|
+
{/if}
|
|
925
|
+
</div>
|
|
926
|
+
</div>
|
|
927
|
+
{/if}
|
|
928
|
+
|
|
929
|
+
{#if !collapsed}
|
|
930
|
+
<div class:code-block-body--expanded={expanded} class="code-block-body">
|
|
931
|
+
{#if !shouldDelayEditor}
|
|
932
|
+
<div bind:this={editorHost} class:is-hidden={showPreFallback} class="code-editor-container"></div>
|
|
933
|
+
{/if}
|
|
934
|
+
{#if showPreFallback}
|
|
935
|
+
<pre class="code-pre-fallback"><code class={preLanguageClass ? `language-${preLanguageClass}` : undefined}>{code}</code></pre>
|
|
936
|
+
{/if}
|
|
937
|
+
</div>
|
|
938
|
+
{/if}
|
|
939
|
+
|
|
940
|
+
{#if previewOpen && isPreviewable}
|
|
941
|
+
<HtmlPreviewFrame code={code} title={previewTitle} isDark={resolvedIsDark} {htmlPreviewAllowScripts} {htmlPreviewSandbox} onClose={() => (previewOpen = false)} />
|
|
942
|
+
{/if}
|
|
943
|
+
</div>
|
|
944
|
+
{/if}
|