@pstdio/workbench 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -88
- package/dist/context-key-service-W4QEfVdN.js +1031 -0
- package/dist/context-key-service-W4QEfVdN.js.map +1 -0
- package/dist/extensions.d.ts +737 -255
- package/dist/extensions.js +891 -699
- package/dist/extensions.js.map +1 -1
- package/dist/file-renderer-view-DrrhYnb_.js.map +1 -1
- package/dist/index.d.ts +746 -448
- package/dist/index.js +2974 -60
- package/dist/index.js.map +1 -1
- package/dist/layout-types-DMoZz38-.js +100 -0
- package/dist/layout-types-DMoZz38-.js.map +1 -0
- package/dist/react.d.ts +735 -231
- package/dist/react.js +3562 -2584
- package/dist/react.js.map +1 -1
- package/dist/storage.d.ts +109 -14
- package/dist/storage.js +142 -47
- package/dist/storage.js.map +1 -1
- package/dist/surface-map-C1pOTUmF.js +52 -0
- package/dist/surface-map-C1pOTUmF.js.map +1 -0
- package/dist/testing.d.ts +685 -198
- package/dist/testing.js +46 -34
- package/dist/testing.js.map +1 -1
- package/dist/webview-runtime.js +5 -1
- package/dist/webview-runtime.js.map +1 -1
- package/dist/workbench-menu-paths-B_QJzcNU.js +12 -0
- package/dist/workbench-menu-paths-B_QJzcNU.js.map +1 -0
- package/package.json +6 -7
- package/dist/context-key-service-C--cHa0B.js +0 -447
- package/dist/context-key-service-C--cHa0B.js.map +0 -1
- package/dist/core.d.ts +0 -1885
- package/dist/core.js +0 -64
- package/dist/core.js.map +0 -1
- package/dist/surface-reconcile-DkRf01ro.js +0 -260
- package/dist/surface-reconcile-DkRf01ro.js.map +0 -1
- package/dist/workbench-core-DFpwi8Lo.js +0 -2264
- package/dist/workbench-core-DFpwi8Lo.js.map +0 -1
- package/dist/workbench-menu-paths-CQVH6z4_.js +0 -11
- package/dist/workbench-menu-paths-CQVH6z4_.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-renderer-view-DrrhYnb_.js","sources":["../src/react/renderers/file/file-kind.ts","../src/react/renderers/file/file-renderer-load-key.ts","../src/react/renderers/file/file-renderer-view.tsx"],"sourcesContent":["// Generic file-type dispatch for the file renderer. Markdown is the default so\n// `.md` / `.txt` / extension-less files open in the prose editor; recognised code\n// extensions open in Monaco; images render read-only. This is deliberately\n// domain-agnostic — it knows about file types, not about tickets.\n\nexport type FileKind = \"markdown\" | \"code\" | \"image\";\n\nconst IMAGE_EXTENSIONS = new Set([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\", \"avif\", \"bmp\", \"ico\"]);\n\n// Extension → Monaco language id. Markdown/plain text intentionally absent so\n// they fall through to the prose editor.\nconst CODE_LANGUAGE_BY_EXTENSION: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"typescript\",\n js: \"javascript\",\n jsx: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n json: \"json\",\n jsonc: \"json\",\n py: \"python\",\n rb: \"ruby\",\n rs: \"rust\",\n go: \"go\",\n java: \"java\",\n kt: \"kotlin\",\n c: \"c\",\n h: \"c\",\n cpp: \"cpp\",\n cc: \"cpp\",\n hpp: \"cpp\",\n cs: \"csharp\",\n php: \"php\",\n swift: \"swift\",\n sh: \"shell\",\n bash: \"shell\",\n zsh: \"shell\",\n sql: \"sql\",\n css: \"css\",\n scss: \"scss\",\n less: \"less\",\n html: \"html\",\n xml: \"xml\",\n yml: \"yaml\",\n yaml: \"yaml\",\n toml: \"ini\",\n ini: \"ini\",\n dockerfile: \"dockerfile\",\n graphql: \"graphql\",\n gql: \"graphql\",\n};\n\nconst extensionOf = (fileName: string | undefined) => {\n if (!fileName) return \"\";\n const dot = fileName.lastIndexOf(\".\");\n if (dot < 0 || dot === fileName.length - 1) return \"\";\n return fileName.slice(dot + 1).toLowerCase();\n};\n\nconst isImage = (fileName: string | undefined, mimeType: string | undefined) => {\n if (mimeType?.startsWith(\"image/\")) return true;\n return IMAGE_EXTENSIONS.has(extensionOf(fileName));\n};\n\nexport const pickFileKind = (fileName: string | undefined, mimeType: string | undefined): FileKind => {\n if (isImage(fileName, mimeType)) return \"image\";\n if (extensionOf(fileName) in CODE_LANGUAGE_BY_EXTENSION) return \"code\";\n return \"markdown\";\n};\n\n// Monaco language for a code file; falls back to plaintext for unknown extensions.\nexport const codeLanguageFor = (fileName: string | undefined) =>\n CODE_LANGUAGE_BY_EXTENSION[extensionOf(fileName)] ?? \"plaintext\";\n","interface FileRendererLoadKeyInput {\n fileRendererId: string;\n resourceUri: string | undefined;\n}\n\nexport const createFileRendererLoadKey = (input: FileRendererLoadKeyInput) => {\n const { fileRendererId, resourceUri } = input;\n return `${fileRendererId}:${resourceUri ?? \"\"}`;\n};\n\nexport const isCurrentLoadedFile = (loaded: { loadKey: string } | null, loadKey: string) => loaded?.loadKey === loadKey;\n","import { Box, Center, Flex, Image, Spinner, Text } from \"@chakra-ui/react\";\nimport { CodeEditor } from \"@pstdio/ui/diff\";\nimport { MarkdownEditor } from \"@pstdio/ui/rich-text\";\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type {\n FileRendererContent,\n RegisteredFileRendererContribution,\n WorkbenchCore,\n WorkbenchWidgetPlacement,\n} from \"../../../core\";\nimport { codeLanguageFor, pickFileKind } from \"./file-kind\";\nimport { createFileRendererLoadKey, isCurrentLoadedFile } from \"./file-renderer-load-key\";\n\ninterface WorkbenchFileRendererViewProps {\n workbench: WorkbenchCore;\n contribution: RegisteredFileRendererContribution;\n // The bound resource (e.g. the open ticket / ticket-file) the load/save\n // commands operate on.\n placement?: WorkbenchWidgetPlacement;\n}\n\ninterface LoadedFile extends FileRendererContent {\n // Bumped on every (re)load so the uncontrolled editors remount with fresh\n // content on a refresh, but never mid-edit (load only runs on mount/refresh).\n revision: number;\n loadKey: string;\n}\n\nconst SAVE_DEBOUNCE_MS = 600;\n\nconst describeError = (error: unknown) => (error instanceof Error ? error.message : \"Failed to load file.\");\n\nexport const WorkbenchFileRendererView = (props: WorkbenchFileRendererViewProps) => {\n const { workbench, contribution } = props;\n const resource = props.placement?.resource;\n const loadKey = createFileRendererLoadKey({ fileRendererId: contribution.id, resourceUri: resource?.uri });\n const [loaded, setLoaded] = useState<LoadedFile | null>(null);\n const [error, setError] = useState<{ loadKey: string; message: string } | null>(null);\n const rendererRef = useRef<HTMLDivElement>(null);\n\n // Re-binding a singleton widget to another resource changes `resource` and reloads.\n useEffect(() => {\n let cancelled = false;\n let revision = 0;\n setError(null);\n setLoaded(null);\n const load = () => {\n Promise.resolve(contribution.load(resource))\n .then((next) => {\n if (cancelled) return;\n revision += 1;\n setError(null);\n setLoaded({ ...next, revision, loadKey });\n })\n .catch((loadError) => {\n if (cancelled) return;\n setError({ loadKey, message: describeError(loadError) });\n });\n };\n load();\n const refreshSubscription = workbench.renderers.onDidRefreshFileRenderer((event) => {\n if (event.fileRendererId === contribution.id) load();\n });\n return () => {\n cancelled = true;\n refreshSubscription.dispose();\n };\n }, [contribution, workbench, resource, loadKey]);\n\n // Debounced autosave shared by the markdown + code editors. Flushed on unmount\n // and when the tab is hidden so the last keystrokes are never dropped.\n const save = contribution.save;\n const pending = useRef<string | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!save) return;\n const flush = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n if (pending.current === null) return;\n const value = pending.current;\n pending.current = null;\n void save(resource, value);\n };\n const onVisibility = () => {\n if (document.visibilityState === \"hidden\") flush();\n };\n window.addEventListener(\"beforeunload\", flush);\n document.addEventListener(\"visibilitychange\", onVisibility);\n return () => {\n window.removeEventListener(\"beforeunload\", flush);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n flush();\n };\n }, [save, resource]);\n\n const handleChange = (value: string) => {\n if (!save) return;\n pending.current = value;\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => {\n timer.current = null;\n if (pending.current === null) return;\n const next = pending.current;\n pending.current = null;\n void save(resource, next);\n }, SAVE_DEBOUNCE_MS);\n };\n\n const currentLoaded = isCurrentLoadedFile(loaded, loadKey) ? loaded : null;\n const scrollResetKey = currentLoaded ? `${currentLoaded.loadKey}:${currentLoaded.revision}` : \"\";\n\n useLayoutEffect(() => {\n if (!scrollResetKey) return;\n const node = rendererRef.current;\n if (!node) return;\n\n requestAnimationFrame(() => {\n let current = node.parentElement;\n while (current) {\n const overflowY = getComputedStyle(current).overflowY;\n if ([\"auto\", \"scroll\", \"overlay\"].includes(overflowY) && current.scrollHeight > current.clientHeight) {\n current.scrollTop = 0;\n }\n current = current.parentElement;\n }\n });\n }, [scrollResetKey]);\n\n if (error?.loadKey === loadKey) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\">\n <Text color=\"fg.muted\">{error.message}</Text>\n </Center>\n );\n }\n\n if (!currentLoaded) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\">\n <Spinner size=\"sm\" />\n </Center>\n );\n }\n\n const kind = pickFileKind(currentLoaded.fileName, currentLoaded.mimeType);\n const isEditable = Boolean(save) && kind !== \"image\";\n const editorKey = `${contribution.id}:${currentLoaded.revision}`;\n\n if (kind === \"image\") {\n if (!currentLoaded.dataUrl) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\">\n <Text color=\"fg.muted\">This image preview is unavailable.</Text>\n </Center>\n );\n }\n return (\n <Center ref={rendererRef} h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\" overflow=\"auto\">\n <Image\n src={currentLoaded.dataUrl}\n alt={currentLoaded.fileName ?? contribution.title}\n maxW=\"100%\"\n maxH=\"100%\"\n objectFit=\"contain\"\n />\n </Center>\n );\n }\n\n if (kind === \"code\") {\n return (\n <Box h=\"full\" minH=\"0\" bg=\"bg\">\n <CodeEditor\n key={editorKey}\n language={codeLanguageFor(currentLoaded.fileName)}\n defaultCode={currentLoaded.content ?? \"\"}\n isEditable={isEditable}\n showLineNumbers\n onChange={isEditable ? handleChange : undefined}\n />\n </Box>\n );\n }\n\n return (\n <Flex ref={rendererRef} direction=\"column\" h=\"full\" minH=\"0\" overflow=\"hidden\" bg=\"bg\">\n <Box flex=\"1\" minH=\"0\" overflowY=\"auto\">\n <MarkdownEditor\n key={editorKey}\n defaultState={currentLoaded.content ?? \"\"}\n isEditable={isEditable}\n placeholder={isEditable ? (currentLoaded.placeholder ?? \"Write…\") : undefined}\n onChange={isEditable ? handleChange : undefined}\n />\n </Box>\n </Flex>\n );\n};\n"],"names":["IMAGE_EXTENSIONS","Set","CODE_LANGUAGE_BY_EXTENSION","ts","tsx","js","jsx","mjs","cjs","json","jsonc","py","rb","rs","go","java","kt","c","h","cpp","cc","hpp","cs","php","swift","sh","bash","zsh","sql","css","scss","less","html","xml","yml","yaml","toml","ini","dockerfile","graphql","gql","extensionOf","fileName","dot","lastIndexOf","length","slice","toLowerCase","isImage","mimeType","startsWith","has","pickFileKind","codeLanguageFor","createFileRendererLoadKey","input","fileRendererId","resourceUri","isCurrentLoadedFile","loaded","loadKey","SAVE_DEBOUNCE_MS","describeError","error","Error","message","WorkbenchFileRendererView","props","$","_c","workbench","contribution","resource","placement","t0","uri","t1","id","setLoaded","useState","setError","rendererRef","useRef","t2","renderers","cancelled","revision","load","Promise","resolve","then","next","catch","loadError","refreshSubscription","onDidRefreshFileRenderer","event","dispose","t3","useEffect","save","pending","timer","t4","t5","flush","current","clearTimeout","value","onVisibility","document","visibilityState","window","addEventListener","removeEventListener","t6","value_0","setTimeout","next_0","handleChange","t7","currentLoaded","scrollResetKey","t8","t9","node","requestAnimationFrame","parentElement","overflowY","getComputedStyle","includes","scrollHeight","clientHeight","scrollTop","useLayoutEffect","t10","Center","Text","Symbol","for","Spinner","kind","isEditable","Boolean","editorKey","dataUrl","t11","title","t12","Image","content","t13","undefined","t14","Box","CodeEditor","placeholder","Flex","MarkdownEditor"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"file-renderer-view-DrrhYnb_.js","sources":["../src/react/renderers/file/file-kind.ts","../src/react/renderers/file/file-renderer-load-key.ts","../src/react/renderers/file/file-renderer-view.tsx"],"sourcesContent":["// Generic file-type dispatch for the file renderer. Markdown is the default so\n// `.md` / `.txt` / extension-less files open in the prose editor; recognised code\n// extensions open in Monaco; images render read-only. This is deliberately\n// domain-agnostic — it knows about file types, not about tickets.\n\nexport type FileKind = \"markdown\" | \"code\" | \"image\";\n\nconst IMAGE_EXTENSIONS = new Set([\"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"svg\", \"avif\", \"bmp\", \"ico\"]);\n\n// Extension → Monaco language id. Markdown/plain text intentionally absent so\n// they fall through to the prose editor.\nconst CODE_LANGUAGE_BY_EXTENSION: Record<string, string> = {\n ts: \"typescript\",\n tsx: \"typescript\",\n js: \"javascript\",\n jsx: \"javascript\",\n mjs: \"javascript\",\n cjs: \"javascript\",\n json: \"json\",\n jsonc: \"json\",\n py: \"python\",\n rb: \"ruby\",\n rs: \"rust\",\n go: \"go\",\n java: \"java\",\n kt: \"kotlin\",\n c: \"c\",\n h: \"c\",\n cpp: \"cpp\",\n cc: \"cpp\",\n hpp: \"cpp\",\n cs: \"csharp\",\n php: \"php\",\n swift: \"swift\",\n sh: \"shell\",\n bash: \"shell\",\n zsh: \"shell\",\n sql: \"sql\",\n css: \"css\",\n scss: \"scss\",\n less: \"less\",\n html: \"html\",\n xml: \"xml\",\n yml: \"yaml\",\n yaml: \"yaml\",\n toml: \"ini\",\n ini: \"ini\",\n dockerfile: \"dockerfile\",\n graphql: \"graphql\",\n gql: \"graphql\",\n};\n\nconst extensionOf = (fileName: string | undefined) => {\n if (!fileName) return \"\";\n const dot = fileName.lastIndexOf(\".\");\n if (dot < 0 || dot === fileName.length - 1) return \"\";\n return fileName.slice(dot + 1).toLowerCase();\n};\n\nconst isImage = (fileName: string | undefined, mimeType: string | undefined) => {\n if (mimeType?.startsWith(\"image/\")) return true;\n return IMAGE_EXTENSIONS.has(extensionOf(fileName));\n};\n\nexport const pickFileKind = (fileName: string | undefined, mimeType: string | undefined): FileKind => {\n if (isImage(fileName, mimeType)) return \"image\";\n if (extensionOf(fileName) in CODE_LANGUAGE_BY_EXTENSION) return \"code\";\n return \"markdown\";\n};\n\n// Monaco language for a code file; falls back to plaintext for unknown extensions.\nexport const codeLanguageFor = (fileName: string | undefined) =>\n CODE_LANGUAGE_BY_EXTENSION[extensionOf(fileName)] ?? \"plaintext\";\n","interface FileRendererLoadKeyInput {\n fileRendererId: string;\n resourceUri: string | undefined;\n}\n\nexport const createFileRendererLoadKey = (input: FileRendererLoadKeyInput) => {\n const { fileRendererId, resourceUri } = input;\n return `${fileRendererId}:${resourceUri ?? \"\"}`;\n};\n\nexport const isCurrentLoadedFile = (loaded: { loadKey: string } | null, loadKey: string) => loaded?.loadKey === loadKey;\n","import { Box, Center, Flex, Image, Spinner, Text } from \"@chakra-ui/react\";\nimport { CodeEditor } from \"@pstdio/ui/diff\";\nimport { MarkdownEditor } from \"@pstdio/ui/rich-text\";\nimport { useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport type {\n FileRendererContent,\n RegisteredFileRendererContribution,\n WorkbenchCore,\n WorkbenchPanelInstance,\n} from \"../../../core\";\nimport { codeLanguageFor, pickFileKind } from \"./file-kind\";\nimport { createFileRendererLoadKey, isCurrentLoadedFile } from \"./file-renderer-load-key\";\n\ninterface WorkbenchFileRendererViewProps {\n workbench: WorkbenchCore;\n contribution: RegisteredFileRendererContribution;\n // The bound resource (e.g. the open ticket / ticket-file) the load/save\n // commands operate on.\n placement?: WorkbenchPanelInstance;\n}\n\ninterface LoadedFile extends FileRendererContent {\n // Bumped on every (re)load so the uncontrolled editors remount with fresh\n // content on a refresh, but never mid-edit (load only runs on mount/refresh).\n revision: number;\n loadKey: string;\n}\n\nconst SAVE_DEBOUNCE_MS = 600;\n\nconst describeError = (error: unknown) => (error instanceof Error ? error.message : \"Failed to load file.\");\n\nexport const WorkbenchFileRendererView = (props: WorkbenchFileRendererViewProps) => {\n const { workbench, contribution } = props;\n const resource = props.placement?.resource;\n const loadKey = createFileRendererLoadKey({ fileRendererId: contribution.id, resourceUri: resource?.uri });\n const [loaded, setLoaded] = useState<LoadedFile | null>(null);\n const [error, setError] = useState<{ loadKey: string; message: string } | null>(null);\n const rendererRef = useRef<HTMLDivElement>(null);\n\n // Re-binding a singleton widget to another resource changes `resource` and reloads.\n useEffect(() => {\n let cancelled = false;\n let revision = 0;\n setError(null);\n setLoaded(null);\n const load = () => {\n Promise.resolve(contribution.load(resource))\n .then((next) => {\n if (cancelled) return;\n revision += 1;\n setError(null);\n setLoaded({ ...next, revision, loadKey });\n })\n .catch((loadError) => {\n if (cancelled) return;\n setError({ loadKey, message: describeError(loadError) });\n });\n };\n load();\n const refreshSubscription = workbench.renderers.onDidRefreshFileRenderer((event) => {\n if (event.fileRendererId === contribution.id) load();\n });\n return () => {\n cancelled = true;\n refreshSubscription.dispose();\n };\n }, [contribution, workbench, resource, loadKey]);\n\n // Debounced autosave shared by the markdown + code editors. Flushed on unmount\n // and when the tab is hidden so the last keystrokes are never dropped.\n const save = contribution.save;\n const pending = useRef<string | null>(null);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!save) return;\n const flush = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n if (pending.current === null) return;\n const value = pending.current;\n pending.current = null;\n void save(resource, value);\n };\n const onVisibility = () => {\n if (document.visibilityState === \"hidden\") flush();\n };\n window.addEventListener(\"beforeunload\", flush);\n document.addEventListener(\"visibilitychange\", onVisibility);\n return () => {\n window.removeEventListener(\"beforeunload\", flush);\n document.removeEventListener(\"visibilitychange\", onVisibility);\n flush();\n };\n }, [save, resource]);\n\n const handleChange = (value: string) => {\n if (!save) return;\n pending.current = value;\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => {\n timer.current = null;\n if (pending.current === null) return;\n const next = pending.current;\n pending.current = null;\n void save(resource, next);\n }, SAVE_DEBOUNCE_MS);\n };\n\n const currentLoaded = isCurrentLoadedFile(loaded, loadKey) ? loaded : null;\n const scrollResetKey = currentLoaded ? `${currentLoaded.loadKey}:${currentLoaded.revision}` : \"\";\n\n useLayoutEffect(() => {\n if (!scrollResetKey) return;\n const node = rendererRef.current;\n if (!node) return;\n\n requestAnimationFrame(() => {\n let current = node.parentElement;\n while (current) {\n const overflowY = getComputedStyle(current).overflowY;\n if ([\"auto\", \"scroll\", \"overlay\"].includes(overflowY) && current.scrollHeight > current.clientHeight) {\n current.scrollTop = 0;\n }\n current = current.parentElement;\n }\n });\n }, [scrollResetKey]);\n\n if (error?.loadKey === loadKey) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\">\n <Text color=\"fg.muted\">{error.message}</Text>\n </Center>\n );\n }\n\n if (!currentLoaded) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\">\n <Spinner size=\"sm\" />\n </Center>\n );\n }\n\n const kind = pickFileKind(currentLoaded.fileName, currentLoaded.mimeType);\n const isEditable = Boolean(save) && kind !== \"image\";\n const editorKey = `${contribution.id}:${currentLoaded.revision}`;\n\n if (kind === \"image\") {\n if (!currentLoaded.dataUrl) {\n return (\n <Center h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\">\n <Text color=\"fg.muted\">This image preview is unavailable.</Text>\n </Center>\n );\n }\n return (\n <Center ref={rendererRef} h=\"full\" minH=\"0\" bg=\"bg\" p=\"md\" overflow=\"auto\">\n <Image\n src={currentLoaded.dataUrl}\n alt={currentLoaded.fileName ?? contribution.title}\n maxW=\"100%\"\n maxH=\"100%\"\n objectFit=\"contain\"\n />\n </Center>\n );\n }\n\n if (kind === \"code\") {\n return (\n <Box h=\"full\" minH=\"0\" bg=\"bg\">\n <CodeEditor\n key={editorKey}\n language={codeLanguageFor(currentLoaded.fileName)}\n defaultCode={currentLoaded.content ?? \"\"}\n isEditable={isEditable}\n showLineNumbers\n onChange={isEditable ? handleChange : undefined}\n />\n </Box>\n );\n }\n\n return (\n <Flex ref={rendererRef} direction=\"column\" h=\"full\" minH=\"0\" overflow=\"hidden\" bg=\"bg\">\n <Box flex=\"1\" minH=\"0\" overflowY=\"auto\">\n <MarkdownEditor\n key={editorKey}\n defaultState={currentLoaded.content ?? \"\"}\n isEditable={isEditable}\n placeholder={isEditable ? (currentLoaded.placeholder ?? \"Write…\") : undefined}\n onChange={isEditable ? handleChange : undefined}\n />\n </Box>\n </Flex>\n );\n};\n"],"names":["IMAGE_EXTENSIONS","Set","CODE_LANGUAGE_BY_EXTENSION","ts","tsx","js","jsx","mjs","cjs","json","jsonc","py","rb","rs","go","java","kt","c","h","cpp","cc","hpp","cs","php","swift","sh","bash","zsh","sql","css","scss","less","html","xml","yml","yaml","toml","ini","dockerfile","graphql","gql","extensionOf","fileName","dot","lastIndexOf","length","slice","toLowerCase","isImage","mimeType","startsWith","has","pickFileKind","codeLanguageFor","createFileRendererLoadKey","input","fileRendererId","resourceUri","isCurrentLoadedFile","loaded","loadKey","SAVE_DEBOUNCE_MS","describeError","error","Error","message","WorkbenchFileRendererView","props","$","_c","workbench","contribution","resource","placement","t0","uri","t1","id","setLoaded","useState","setError","rendererRef","useRef","t2","renderers","cancelled","revision","load","Promise","resolve","then","next","catch","loadError","refreshSubscription","onDidRefreshFileRenderer","event","dispose","t3","useEffect","save","pending","timer","t4","t5","flush","current","clearTimeout","value","onVisibility","document","visibilityState","window","addEventListener","removeEventListener","t6","value_0","setTimeout","next_0","handleChange","t7","currentLoaded","scrollResetKey","t8","t9","node","requestAnimationFrame","parentElement","overflowY","getComputedStyle","includes","scrollHeight","clientHeight","scrollTop","useLayoutEffect","t10","Center","Text","Symbol","for","Spinner","kind","isEditable","Boolean","editorKey","dataUrl","t11","title","t12","Image","content","t13","undefined","t14","Box","CodeEditor","placeholder","Flex","MarkdownEditor"],"mappings":"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"}
|