UNPKG

vue-shiki-monaco

Version:
336 lines (335 loc) 11.5 kB
import { defineComponent, ref, watch, onMounted, onUnmounted, onBeforeUnmount, createElementBlock, openBlock, normalizeClass, createBlock, createCommentVNode, createElementVNode, withCtx, renderSlot, normalizeStyle, unref } from "vue"; import { u as useMonacoEdit } from "../../index-Bl0GB3kH.js"; import MonacoHeader from "../Monaco-Header/index.js"; import ContextMenu from "../ContextMenu/index.js"; import { u as useContextMenu, M as MENU_PRESETS, c as createEditorContextMenu, b as MINIMAP_MENU_PRESETS, a as createMinimapContextMenu } from "../../editorMenu-BFs5QkAV.js"; import '../../global.css';import './index.css';/* empty css */ import { _ as _export_sfc } from "../../_plugin-vue_export-helper-1tPrXgE0.js"; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "index", props: { currentLanguage: { default: "javascript" }, currentTheme: { default: "vitesse-light" }, languages: { default: () => [ "javascript", "typescript", "python", "html", "css", "json" ] }, themes: { default: () => [ "vitesse-light", "vitesse-dark", "github-light", "github-dark" ] }, value: { default: "" }, height: { default: "400px" }, showToolbar: { type: Boolean, default: true }, autoResize: { type: Boolean, default: true }, monacoEditClass: {}, fileName: {}, contextMenu: { default: () => ({ enabled: true, items: "full", variant: "glass" }) }, minimapContextMenu: { default: () => ({ enabled: true, items: "basic", variant: "glass" }) }, teleportTarget: {} }, emits: ["change", "ready"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emit = __emit; const editorRef = ref(); let editorInstance = null; let monacoEditHook = null; const contextMenuItems = ref([]); const contextMenu = useContextMenu({ items: contextMenuItems.value }); const minimapContextMenuItems = ref([]); const minimapContextMenu = useContextMenu({ items: minimapContextMenuItems.value }); watch( () => props.value, (value) => { if (editorInstance) { editorInstance.setValue(value); } }, { deep: 1 } ); watch( () => props.currentTheme, async (newTheme) => { if (monacoEditHook && editorInstance) { try { await monacoEditHook.setTheme(newTheme); } catch (error) { } } } ); watch( () => props.currentLanguage, async (newLanguage) => { if (monacoEditHook && editorInstance) { try { await monacoEditHook.setLanguage(newLanguage); } catch (error) { } } } ); const initializeEditor = async () => { if (!editorRef.value) return; monacoEditHook = useMonacoEdit({ target: editorRef.value, languages: props.languages, themes: props.themes, codeValue: props.value, defaultTheme: props.currentTheme, defaultLanguage: props.currentLanguage, contextMenu: props.contextMenu }); try { editorInstance = await monacoEditHook.initMonacoEdit(); editorInstance.onDidChangeModelContent(() => { const value = editorInstance?.getValue() || ""; emit("change", value); }); emit("ready", editorInstance); if (props.contextMenu?.enabled !== false) { setupContextMenu(); } if (props.autoResize) { monacoEditHook.enableAutoResize(); } } catch (error) { throw error; } }; onMounted(async () => { await initializeEditor(); }); onUnmounted(() => { if (monacoEditHook) { monacoEditHook.destroy(); } }); const handleCopy = async () => { if (editorInstance) { try { const code = editorInstance.getValue(); if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(code); return; } const textArea = document.createElement("textarea"); textArea.value = code; textArea.style.position = "fixed"; textArea.style.left = "-999999px"; textArea.style.top = "-999999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); const successful = document.execCommand("copy"); document.body.removeChild(textArea); if (successful) { } else { throw new Error("降级复制方案失败"); } } catch (error) { try { const selection = editorInstance.getSelection(); if (selection && !selection.isEmpty()) { editorInstance.trigger( "keyboard", "editor.action.clipboardCopyAction", null ); } } catch (monacoError) { } } } }; const handleFormat = () => { if (editorInstance) { editorInstance.getAction("editor.action.formatDocument")?.run(); } }; const handlePaste = async () => { if (editorInstance) { try { const pasteAction = editorInstance.getAction( "editor.action.clipboardPasteAction" ); if (pasteAction) { pasteAction.run(); return; } try { editorInstance.trigger( "keyboard", "editor.action.clipboardPasteAction", null ); return; } catch (triggerError) { } const text = await navigator.clipboard.readText(); if (text) { const selection = editorInstance.getSelection(); if (selection) { editorInstance.executeEdits("paste", [ { range: selection, text, forceMoveMarkers: true } ]); editorInstance.focus(); } } } catch (error) { } } }; const setupContextMenu = () => { if (!editorInstance || !monacoEditHook) return; if (props.contextMenu?.enabled !== false) { let enabledItems = []; if (typeof props.contextMenu?.items === "string") { enabledItems = MENU_PRESETS[props.contextMenu.items]; } else if (Array.isArray(props.contextMenu?.items)) { enabledItems = props.contextMenu.items; } contextMenuItems.value = createEditorContextMenu({ editor: editorInstance, enabledItems, customItems: props.contextMenu?.customItems ?? [] }); monacoEditHook.onContextMenu(async (event) => { if (minimapContextMenu.isVisible.value) { minimapContextMenu.hide(); } try { if ("permissions" in navigator) { await navigator.permissions.query({ name: "clipboard-read" }); } } catch (error) { } contextMenu.show(event, contextMenuItems.value, editorRef.value); }); } if (props.minimapContextMenu?.enabled !== false) { let minimapEnabledItems = []; if (typeof props.minimapContextMenu?.items === "string") { minimapEnabledItems = MINIMAP_MENU_PRESETS[props.minimapContextMenu.items]; } else if (Array.isArray(props.minimapContextMenu?.items)) { minimapEnabledItems = props.minimapContextMenu.items; } minimapContextMenuItems.value = createMinimapContextMenu({ editor: editorInstance, enabledItems: minimapEnabledItems, customItems: props.minimapContextMenu?.customItems ?? [] }); monacoEditHook.onMinimapContextMenu(async (event) => { if (contextMenu.isVisible.value) { contextMenu.hide(); } minimapContextMenu.show(event, minimapContextMenuItems.value, editorRef.value); }); } }; const handleContextMenuItemClick = (item) => { if (item.type === "item") { item.action(); contextMenu.hide(); } }; const handleMinimapContextMenuItemClick = (item) => { if (item.type === "item") { item.action(); minimapContextMenu.hide(); } }; onBeforeUnmount(() => { monacoEditHook?.destroy(); }); __expose({ getEditor: () => editorInstance, setValue: (value) => editorInstance?.setValue(value), getValue: () => editorInstance?.getValue() || "", focus: () => editorInstance?.focus(), setTheme: (theme) => monacoEditHook?.setTheme(theme), setLanguage: (language) => monacoEditHook?.setLanguage(language), layout: () => monacoEditHook?.layout(), enableAutoResize: () => monacoEditHook?.enableAutoResize(), disableAutoResize: () => monacoEditHook?.disableAutoResize(), copyCode: handleCopy, pasteCode: handlePaste, formatCode: handleFormat }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass(["monaco-editor-wrapper", props.monacoEditClass]) }, [ props.showToolbar ? (openBlock(), createBlock(MonacoHeader, { key: 0, "current-language": props.currentLanguage, "file-name": props.fileName ?? "Untitled", theme: props.currentTheme, onCopy: handleCopy, onFormat: handleFormat }, { toolbar: withCtx(() => [ renderSlot(_ctx.$slots, "toolbar", {}, void 0, true) ]), _: 3 }, 8, ["current-language", "file-name", "theme"])) : createCommentVNode("", true), createElementVNode("div", { ref_key: "editorRef", ref: editorRef, class: normalizeClass(["monaco-editor", { noHeader: !props.showToolbar }]), style: normalizeStyle({ height: props.height }) }, null, 6), editorRef.value ? (openBlock(), createBlock(ContextMenu, { key: 1, visible: unref(contextMenu).isVisible.value, position: unref(contextMenu).position, items: contextMenuItems.value, variant: props.contextMenu?.variant || "glass", theme: props.currentTheme, onItemClick: handleContextMenuItemClick, onHide: unref(contextMenu).hide }, null, 8, ["visible", "position", "items", "variant", "theme", "onHide"])) : createCommentVNode("", true), editorRef.value ? (openBlock(), createBlock(ContextMenu, { key: 2, visible: unref(minimapContextMenu).isVisible.value, position: unref(minimapContextMenu).position, items: minimapContextMenuItems.value, variant: props.minimapContextMenu?.variant || "glass", theme: props.currentTheme, onItemClick: handleMinimapContextMenuItemClick, onHide: unref(minimapContextMenu).hide }, null, 8, ["visible", "position", "items", "variant", "theme", "onHide"])) : createCommentVNode("", true) ], 2); }; } }); const Monaco = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6b55436b"]]); export { Monaco as default }; //# sourceMappingURL=index.js.map