smart-code-editor 1.0.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 +155 -0
- package/lib/adapters/vanilla/index.d.ts +3 -0
- package/lib/adapters/vanilla/index.d.ts.map +1 -0
- package/lib/config/languages.d.ts +21 -0
- package/lib/config/languages.d.ts.map +1 -0
- package/lib/config/runnerStrategies.d.ts +12 -0
- package/lib/config/runnerStrategies.d.ts.map +1 -0
- package/lib/config/runnerStrategies_v2.d.ts +31 -0
- package/lib/config/runnerStrategies_v2.d.ts.map +1 -0
- package/lib/config/themes.d.ts +54 -0
- package/lib/config/themes.d.ts.map +1 -0
- package/lib/core/BackendRunner.d.ts +78 -0
- package/lib/core/BackendRunner.d.ts.map +1 -0
- package/lib/core/CodeRunner.d.ts +32 -0
- package/lib/core/CodeRunner.d.ts.map +1 -0
- package/lib/core/LanguageManager.d.ts +41 -0
- package/lib/core/LanguageManager.d.ts.map +1 -0
- package/lib/core/LayoutManager.d.ts +59 -0
- package/lib/core/LayoutManager.d.ts.map +1 -0
- package/lib/core/MonacoWrapper.d.ts +63 -0
- package/lib/core/MonacoWrapper.d.ts.map +1 -0
- package/lib/core/SmartCodeEditor.d.ts +140 -0
- package/lib/core/SmartCodeEditor.d.ts.map +1 -0
- package/lib/dev-main.d.ts +2 -0
- package/lib/dev-main.d.ts.map +1 -0
- package/lib/index.cjs +242 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1369 -0
- package/lib/index.umd.cjs +242 -0
- package/lib/shims-vue.d.ts +4 -0
- package/lib/types/index.d.ts +101 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/language.d.ts +37 -0
- package/lib/types/language.d.ts.map +1 -0
- package/lib/types/question.d.ts +75 -0
- package/lib/types/question.d.ts.map +1 -0
- package/lib/utils/loader.d.ts +9 -0
- package/lib/utils/loader.d.ts.map +1 -0
- package/lib/utils/markdown.d.ts +2 -0
- package/lib/utils/markdown.d.ts.map +1 -0
- package/package.json +72 -0
- package/src/adapters/vanilla/index.ts +7 -0
- package/src/adapters/vue/SmartCodeEditor.vue +1190 -0
- package/src/config/languages.ts +273 -0
- package/src/config/runnerStrategies.ts +261 -0
- package/src/config/runnerStrategies_v2.ts +182 -0
- package/src/config/themes.ts +37 -0
- package/src/core/BackendRunner.ts +329 -0
- package/src/core/CodeRunner.ts +107 -0
- package/src/core/LanguageManager.ts +108 -0
- package/src/core/LayoutManager.ts +268 -0
- package/src/core/MonacoWrapper.ts +173 -0
- package/src/core/SmartCodeEditor.ts +1015 -0
- package/src/dev-app.vue +488 -0
- package/src/dev-main.ts +7 -0
- package/src/index.ts +19 -0
- package/src/shims-vue.d.ts +4 -0
- package/src/types/index.ts +129 -0
- package/src/types/language.ts +44 -0
- package/src/types/question.ts +98 -0
- package/src/utils/loader.ts +69 -0
- package/src/utils/markdown.ts +89 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { SmartCodeEditorOptions, RunResult, LanguageConfig, QuestionMarkdownOptions } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 智能代码编辑器主类
|
|
5
|
+
* 所有业务逻辑的入口点
|
|
6
|
+
*/
|
|
7
|
+
export declare class SmartCodeEditor {
|
|
8
|
+
private container;
|
|
9
|
+
private options;
|
|
10
|
+
private monacoWrapper;
|
|
11
|
+
private layoutManager;
|
|
12
|
+
private languageManager;
|
|
13
|
+
private codeRunner;
|
|
14
|
+
private id;
|
|
15
|
+
private initialized;
|
|
16
|
+
private _pendingLanguage;
|
|
17
|
+
private _pendingValue;
|
|
18
|
+
private resizeObserver;
|
|
19
|
+
private loadingMask;
|
|
20
|
+
private toolbar;
|
|
21
|
+
private langSelect;
|
|
22
|
+
private markdownEditor;
|
|
23
|
+
private markdownPreview;
|
|
24
|
+
constructor(options: SmartCodeEditorOptions);
|
|
25
|
+
/**
|
|
26
|
+
* 显示加载遮罩
|
|
27
|
+
*/
|
|
28
|
+
private showLoading;
|
|
29
|
+
/**
|
|
30
|
+
* 隐藏加载遮罩
|
|
31
|
+
*/
|
|
32
|
+
private hideLoading;
|
|
33
|
+
/**
|
|
34
|
+
* 创建 Markdown 题目面板
|
|
35
|
+
*/
|
|
36
|
+
private createMarkdownPanel;
|
|
37
|
+
/**
|
|
38
|
+
* 初始化
|
|
39
|
+
*/
|
|
40
|
+
private init;
|
|
41
|
+
/**
|
|
42
|
+
* 创建工具栏
|
|
43
|
+
*/
|
|
44
|
+
private createToolbar;
|
|
45
|
+
/**
|
|
46
|
+
* 创建语言选择器
|
|
47
|
+
*/
|
|
48
|
+
private createLanguageSelector;
|
|
49
|
+
/**
|
|
50
|
+
* 创建运行按钮
|
|
51
|
+
*/
|
|
52
|
+
private createRunButton;
|
|
53
|
+
/**
|
|
54
|
+
* 创建提交按钮
|
|
55
|
+
*/
|
|
56
|
+
private createSubmitButton;
|
|
57
|
+
private injectSpinnerStyle;
|
|
58
|
+
/**
|
|
59
|
+
* 获取代码
|
|
60
|
+
*/
|
|
61
|
+
getValue(): string;
|
|
62
|
+
/**
|
|
63
|
+
* 设置代码
|
|
64
|
+
*/
|
|
65
|
+
setValue(value: string): void;
|
|
66
|
+
/**
|
|
67
|
+
* 获取当前语言
|
|
68
|
+
*/
|
|
69
|
+
getLanguage(): string;
|
|
70
|
+
/**
|
|
71
|
+
* 设置语言
|
|
72
|
+
*/
|
|
73
|
+
setLanguage(language: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* 获取支持的语言列表
|
|
76
|
+
*/
|
|
77
|
+
getSupportedLanguages(): LanguageConfig[];
|
|
78
|
+
/**
|
|
79
|
+
* 设置主题
|
|
80
|
+
*/
|
|
81
|
+
setTheme(theme: string): void;
|
|
82
|
+
/**
|
|
83
|
+
* 获取主题
|
|
84
|
+
*/
|
|
85
|
+
getTheme(): string;
|
|
86
|
+
/**
|
|
87
|
+
* 设置试题内容
|
|
88
|
+
*/
|
|
89
|
+
setQuestionContent(content: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* 设置 Markdown 题目内容
|
|
92
|
+
*/
|
|
93
|
+
setQuestionMarkdown(value: string, options?: Partial<QuestionMarkdownOptions>): void;
|
|
94
|
+
/**
|
|
95
|
+
* 显示试题面板
|
|
96
|
+
*/
|
|
97
|
+
showQuestionPanel(): void;
|
|
98
|
+
/**
|
|
99
|
+
* 隐藏试题面板
|
|
100
|
+
*/
|
|
101
|
+
hideQuestionPanel(): void;
|
|
102
|
+
private testCases;
|
|
103
|
+
/**
|
|
104
|
+
* 设置测试用例
|
|
105
|
+
*/
|
|
106
|
+
setTestCases(testCases: import('../types').TestCase[]): void;
|
|
107
|
+
/**
|
|
108
|
+
* 运行代码
|
|
109
|
+
*/
|
|
110
|
+
run(testCases?: import('../types').TestCase[]): Promise<RunResult>;
|
|
111
|
+
/**
|
|
112
|
+
* 取消运行
|
|
113
|
+
*/
|
|
114
|
+
cancelRun(): void;
|
|
115
|
+
/**
|
|
116
|
+
* 调整布局
|
|
117
|
+
*/
|
|
118
|
+
resize(): void;
|
|
119
|
+
/**
|
|
120
|
+
* 设置分割比例
|
|
121
|
+
*/
|
|
122
|
+
setSplitRatio(ratio: number): void;
|
|
123
|
+
/**
|
|
124
|
+
* 重新布局
|
|
125
|
+
*/
|
|
126
|
+
layout(): void;
|
|
127
|
+
/**
|
|
128
|
+
* 更新配置
|
|
129
|
+
*/
|
|
130
|
+
updateConfig(config: Partial<SmartCodeEditorOptions>): void;
|
|
131
|
+
/**
|
|
132
|
+
* 刷新语言选择器
|
|
133
|
+
*/
|
|
134
|
+
private refreshLanguageSelector;
|
|
135
|
+
/**
|
|
136
|
+
* 销毁
|
|
137
|
+
*/
|
|
138
|
+
destroy(): void;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=SmartCodeEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SmartCodeEditor.d.ts","sourceRoot":"","sources":["../../src/core/SmartCodeEditor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,SAAS,EACT,cAAc,EACd,uBAAuB,EACxB,MAAM,UAAU,CAAC;AAQlB;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,OAAO,CAAyB;IAGxC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,UAAU,CAAa;IAG/B,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,eAAe,CAA4B;gBAEvC,OAAO,EAAE,sBAAsB;IAyB3C;;OAEG;IACH,OAAO,CAAC,WAAW;IA8BnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA+J3B;;OAEG;YACW,IAAI;IA4JlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAiDrB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA4D9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAkDvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkD1B,OAAO,CAAC,kBAAkB;IAsB1B;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ7B;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IA2BnC;;OAEG;IACH,qBAAqB,IAAI,cAAc,EAAE;IAIzC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA8B7B;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMzC;;OAEG;IACH,mBAAmB,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GACzC,IAAI;IAeP;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB,OAAO,CAAC,SAAS,CAAqC;IAEtD;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,OAAO,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI;IAI5D;;OAEG;IACG,GAAG,CAAC,SAAS,CAAC,EAAE,OAAO,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAgFxE;;OAEG;IACH,SAAS,IAAI,IAAI;IAIjB;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlC;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,IAAI;IAiC3D;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA4B/B;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-main.d.ts","sourceRoot":"","sources":["../src/dev-main.ts"],"names":[],"mappings":""}
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function _(){return typeof window.monaco<"u"?Promise.resolve(window.monaco):new Promise((h,e)=>{const t=window,n=t.__SCE_MONACO_LOADER_URL__,i=t.__SCE_MONACO_BASE_PATH__,s=n?[n]:i?[`${String(i).replace(/\/$/,"")}/loader.js`]:["/package/min/vs/loader.js","/package/vs/loader.js"],l=r=>{if(r>=s.length){e(new Error("Monaco loader not found"));return}const c=s[r],u=document.createElement("script");u.src=c,u.onload=()=>{const p=c.replace(/\/loader\.js(\?.*)?$/,"");window.require.config({paths:{vs:p}}),window.require(["vs/editor/editor.main"],()=>{h(window.monaco)})},u.onerror=()=>{u.remove(),l(r+1)},document.body.appendChild(u)};l(0)})}function M(h,e){let t;return function(...n){clearTimeout(t),t=setTimeout(()=>{h.apply(this,n)},e)}}class E{constructor(e){this.editor=null,this.monaco=null,this.container=e}async initialize(e={}){this.monaco=await _(),this.editor=this.monaco.editor.create(this.container,{value:e.value||"",language:e.language||"javascript",theme:e.theme||"vs-dark",readOnly:e.readOnly||!1,fontSize:e.fontSize||14,minimap:e.minimap||{enabled:!0},lineNumbers:e.lineNumbers||"on",automaticLayout:e.automaticLayout!==!1,scrollBeyondLastLine:!1,roundedSelection:!0,padding:{top:16},suggestOnTriggerCharacters:e.suggestOnTriggerCharacters!==void 0?e.suggestOnTriggerCharacters:!0,quickSuggestions:e.quickSuggestions!==void 0?e.quickSuggestions:!0,tabSize:2})}setValue(e){this.editor&&this.editor.setValue(e)}getValue(){return this.editor?this.editor.getValue():""}updateModel(e,t,n="",i="default"){if(this.editor&&this.monaco){const a=this.editor.getModel(),s=n.startsWith(".")?n:`.${n}`,l=this.monaco.Uri.parse(`file:///${i}/main${s}`);let r=this.monaco.editor.getModel(l);r?(r.setValue(e),this.monaco.editor.setModelLanguage(r,t)):r=this.monaco.editor.createModel(e,t,l),this.editor.setModel(r),a&&a!==r&&a.dispose()}}setTheme(e){this.editor&&this.monaco&&this.monaco.editor.setTheme(e)}setReadOnly(e){this.editor&&this.editor.updateOptions({readOnly:e})}updateOptions(e){this.editor&&this.editor.updateOptions(e)}onDidChangeContent(e){this.editor&&this.editor.onDidChangeModelContent(()=>{e(this.getValue())})}layout(){this.editor&&this.editor.layout()}getMonaco(){return this.monaco}getEditor(){return this.editor}dispose(){this.editor&&(this.editor.dispose(),this.editor=null)}}class ${constructor(e,t=.48,n="vs-dark"){this.isDragging=!1,this.startX=0,this.startLeftWidth=0,this.handleMouseDown=i=>{this.isDragging=!0,this.startX=i.clientX,this.startLeftWidth=this.leftPanel.offsetWidth,this.splitter.style.background="#4CAF50",document.body.style.cursor="col-resize",document.body.style.userSelect="none",i.preventDefault()},this.handleMouseMove=i=>{if(!this.isDragging)return;const a=i.clientX-this.startX,s=this.startLeftWidth+a,l=this.container.offsetWidth,r=200,c=l-400-8;if(s>=r&&s<=c){const u=s/l;this.leftPanel.style.width=`${u*100}%`}},this.handleMouseUp=()=>{this.isDragging&&(this.isDragging=!1,this.splitter.style.background="#f5f5f5",document.body.style.cursor="",document.body.style.userSelect="")},this.container=e,this.leftPanel=document.createElement("div"),this.splitter=document.createElement("div"),this.rightPanel=document.createElement("div"),this.initLayout(t,n),this.initResizable()}initLayout(e,t){this.container.style.display="flex",this.container.style.height="100%",this.container.style.position="relative";const n=document.createElement("div");n.className="sce-editor-wrapper",n.style.display="flex",n.style.height="100%",n.style.width="100%",n.style.overflow="hidden",this.leftPanel.className="sce-question-panel",this.leftPanel.style.width=`${e*100}%`,this.leftPanel.style.minWidth="200px",this.leftPanel.style.overflow="auto",this.leftPanel.style.padding="14px 6px 14px 14px",this.leftPanel.style.boxSizing="border-box",this.splitter.className="sce-splitter",this.splitter.style.width="2px",this.splitter.style.cursor="col-resize",this.splitter.style.flexShrink="0",this.splitter.style.userSelect="none",this.splitter.style.margin="0 6px";const i=document.createElement("div");i.className="sce-right-container",i.style.flex="1",i.style.minWidth="400px",i.style.minHeight="0",i.style.display="flex",i.style.flexDirection="column",i.style.overflow="hidden",this.rightPanel.className="sce-editor-panel",this.rightPanel.style.flex="1",this.rightPanel.style.minHeight="0",this.rightPanel.style.overflow="hidden",this.rightPanel.style.position="relative",this.rightPanel.style.display="flex",this.rightPanel.style.flexDirection="column",this.setTheme(t),i.appendChild(this.rightPanel),n.appendChild(this.leftPanel),n.appendChild(this.splitter),n.appendChild(i),this.container.appendChild(n)}initResizable(){this.splitter.addEventListener("mousedown",this.handleMouseDown),document.addEventListener("mousemove",this.handleMouseMove),document.addEventListener("mouseup",this.handleMouseUp)}setLeftContent(e){typeof e=="string"?(this.leftPanel.innerHTML=e,this.leftPanel.style.overflow="auto"):(this.leftPanel.innerHTML="",this.leftPanel.appendChild(e),e.classList.contains("sce-question-markdown")?this.leftPanel.style.overflow="hidden":this.leftPanel.style.overflow="auto")}getRightContainer(){return this.rightPanel}setQuestionPanelVisible(e){e?(this.leftPanel.style.display="block",this.splitter.style.display="block"):(this.leftPanel.style.display="none",this.splitter.style.display="none")}setSplitRatio(e){this.leftPanel.style.width=`${e*100}%`}setTheme(e){const t=e==="vs-dark";t?(this.leftPanel.style.background="#1e1e1e",this.leftPanel.style.color="#d4d4d4",this.splitter.style.background="#252526"):(this.leftPanel.style.background="#ffffff",this.leftPanel.style.color="#333333",this.splitter.style.background="#f5f5f5");const n=this.leftPanel.querySelector(".sce-markdown-editor"),i=this.leftPanel.querySelector(".sce-markdown-preview"),a=this.leftPanel.querySelectorAll(".sce-markdown-label"),s=this.leftPanel.querySelectorAll(".sce-markdown-tab");n&&(n.style.background=t?"#1e1e1e":"#ffffff",n.style.color=t?"#d4d4d4":"#333333",n.style.border=t?"1px solid #333":"1px solid #ddd"),i&&(i.style.background=t?"#1b1b1b":"#ffffff",i.style.color=t?"#d4d4d4":"#333333"),a.forEach(l=>{l.style.color=t?"#c5c5c5":"#666666"}),s.forEach(l=>{const r=l,c=r.classList.contains("active");r.style.border=t?"1px solid #3a3a3a":"1px solid #ddd",r.style.background=c?t?"#2d2d30":"#f3f3f3":t?"#1f1f1f":"#ffffff",r.style.color=t?"#d4d4d4":"#333333",r.style.borderRadius="6px",r.style.padding="4px 10px",r.style.fontSize="12px",r.style.cursor="pointer"})}destroy(){document.removeEventListener("mousemove",this.handleMouseMove),document.removeEventListener("mouseup",this.handleMouseUp),this.container.innerHTML=""}}const x=[{id:"javascript",name:"JavaScript",monacoId:"javascript",extensions:[".js"],fallbackTemplate:`// JavaScript 示例
|
|
2
|
+
console.log("Hello, World!");
|
|
3
|
+
|
|
4
|
+
// 定义一个函数
|
|
5
|
+
function fibonacci(n) {
|
|
6
|
+
if (n <= 1) return n;
|
|
7
|
+
return fibonacci(n - 1) + fibonacci(n - 2);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
console.log("斐波那契数列前10项:");
|
|
11
|
+
for (let i = 0; i < 10; i++) {
|
|
12
|
+
console.log(\`F(\${i}) = \${fibonacci(i)}\`);
|
|
13
|
+
}`,canRun:!0},{id:"typescript",name:"TypeScript",monacoId:"typescript",extensions:[".ts"],fallbackTemplate:`// TypeScript 示例
|
|
14
|
+
interface User {
|
|
15
|
+
name: string;
|
|
16
|
+
age: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const user: User = {
|
|
20
|
+
name: "张三",
|
|
21
|
+
age: 25
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
console.log(\`用户: \${user.name}, 年龄: \${user.age}\`);`,canRun:!0},{id:"python",name:"Python",monacoId:"python",extensions:[".py"],fallbackTemplate:`# Python 示例
|
|
25
|
+
print("Hello, World!")
|
|
26
|
+
|
|
27
|
+
# 列表推导式
|
|
28
|
+
squares = [x**2 for x in range(10)]
|
|
29
|
+
print("前10个平方数:", squares)
|
|
30
|
+
|
|
31
|
+
# 定义一个类
|
|
32
|
+
class Person:
|
|
33
|
+
def __init__(self, name, age):
|
|
34
|
+
self.name = name
|
|
35
|
+
self.age = age
|
|
36
|
+
|
|
37
|
+
def greet(self):
|
|
38
|
+
return f"你好,我是{self.name},今年{self.age}岁"
|
|
39
|
+
|
|
40
|
+
person = Person("李四", 30)
|
|
41
|
+
print(person.greet())`,canRun:!0},{id:"html",name:"HTML",monacoId:"html",fallbackTemplate:`<!DOCTYPE html>
|
|
42
|
+
<html lang="zh-CN">
|
|
43
|
+
<head>
|
|
44
|
+
<meta charset="UTF-8">
|
|
45
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
46
|
+
<title>Hello HTML</title>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<h1>欢迎使用智能代码编辑器</h1>
|
|
50
|
+
<p>这是一个 HTML 示例</p>
|
|
51
|
+
</body>
|
|
52
|
+
</html>`,canRun:!1,extensions:[".html"]},{id:"css",name:"CSS",monacoId:"css",fallbackTemplate:`/* CSS 示例 */
|
|
53
|
+
body {
|
|
54
|
+
font-family: 'Arial', sans-serif;
|
|
55
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
56
|
+
color: white;
|
|
57
|
+
padding: 20px;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.container {
|
|
61
|
+
max-width: 1200px;
|
|
62
|
+
margin: 0 auto;
|
|
63
|
+
background: rgba(255, 255, 255, 0.1);
|
|
64
|
+
border-radius: 10px;
|
|
65
|
+
padding: 30px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
h1 {
|
|
69
|
+
font-size: 2.5rem;
|
|
70
|
+
margin-bottom: 20px;
|
|
71
|
+
}`,canRun:!1,extensions:[".css"]},{id:"java",name:"Java",monacoId:"java",fallbackTemplate:`public class HelloWorld {
|
|
72
|
+
public static void main(String[] args) {
|
|
73
|
+
System.out.println("Hello, World!");
|
|
74
|
+
|
|
75
|
+
// 数组示例
|
|
76
|
+
int[] numbers = {1, 2, 3, 4, 5};
|
|
77
|
+
int sum = 0;
|
|
78
|
+
for (int num : numbers) {
|
|
79
|
+
sum += num;
|
|
80
|
+
}
|
|
81
|
+
System.out.println("数组总和: " + sum);
|
|
82
|
+
}
|
|
83
|
+
}`,canRun:!0,extensions:[".java"]},{id:"cpp",name:"C++",monacoId:"cpp",fallbackTemplate:`#include <iostream>
|
|
84
|
+
#include <vector>
|
|
85
|
+
using namespace std;
|
|
86
|
+
|
|
87
|
+
int main() {
|
|
88
|
+
cout << "Hello, World!" << endl;
|
|
89
|
+
|
|
90
|
+
// 向量示例
|
|
91
|
+
vector<int> vec = {1, 2, 3, 4, 5};
|
|
92
|
+
int sum = 0;
|
|
93
|
+
for(int num : vec) {
|
|
94
|
+
sum += num;
|
|
95
|
+
}
|
|
96
|
+
cout << "向量总和: " << sum << endl;
|
|
97
|
+
|
|
98
|
+
return 0;
|
|
99
|
+
}`,canRun:!0,extensions:[".cpp",".cc",".cxx"]},{id:"go",name:"Go",monacoId:"go",fallbackTemplate:`package main
|
|
100
|
+
|
|
101
|
+
import "fmt"
|
|
102
|
+
|
|
103
|
+
func main() {
|
|
104
|
+
fmt.Println("Hello, World!")
|
|
105
|
+
|
|
106
|
+
// 切片示例
|
|
107
|
+
numbers := []int{1, 2, 3, 4, 5}
|
|
108
|
+
sum := 0
|
|
109
|
+
for _, num := range numbers {
|
|
110
|
+
sum += num
|
|
111
|
+
}
|
|
112
|
+
fmt.Printf("切片总和: %d\\n", sum)
|
|
113
|
+
}`,canRun:!0,extensions:[".go"]},{id:"rust",name:"Rust",monacoId:"rust",fallbackTemplate:`fn main() {
|
|
114
|
+
println!("Hello, World!");
|
|
115
|
+
|
|
116
|
+
// 向量示例
|
|
117
|
+
let numbers = vec![1, 2, 3, 4, 5];
|
|
118
|
+
let sum: i32 = numbers.iter().sum();
|
|
119
|
+
println!("总和: {}", sum);
|
|
120
|
+
}`,canRun:!0,extensions:[".rs"]},{id:"c",name:"C",monacoId:"c",fallbackTemplate:`#include <stdio.h>
|
|
121
|
+
|
|
122
|
+
int main() {
|
|
123
|
+
printf("Hello, World!\\n");
|
|
124
|
+
|
|
125
|
+
// 数组示例
|
|
126
|
+
int numbers[] = {1, 2, 3, 4, 5};
|
|
127
|
+
int sum = 0;
|
|
128
|
+
int size = sizeof(numbers) / sizeof(numbers[0]);
|
|
129
|
+
|
|
130
|
+
for(int i = 0; i < size; i++) {
|
|
131
|
+
sum += numbers[i];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
printf("数组总和: %d\\n", sum);
|
|
135
|
+
return 0;
|
|
136
|
+
}`,canRun:!0,extensions:[".c"]},{id:"sql",name:"SQL",monacoId:"sql",fallbackTemplate:`-- SQL 示例
|
|
137
|
+
SELECT
|
|
138
|
+
users.name,
|
|
139
|
+
users.email,
|
|
140
|
+
COUNT(orders.id) as order_count,
|
|
141
|
+
SUM(orders.amount) as total_amount
|
|
142
|
+
FROM users
|
|
143
|
+
LEFT JOIN orders ON users.id = orders.user_id
|
|
144
|
+
WHERE users.created_at >= '2024-01-01'
|
|
145
|
+
GROUP BY users.id, users.name, users.email
|
|
146
|
+
HAVING COUNT(orders.id) > 0
|
|
147
|
+
ORDER BY total_amount DESC
|
|
148
|
+
LIMIT 10;`,canRun:!1,extensions:[".sql"]}];function N(h){return x.find(e=>e.id===h)}function W(){return x}class H{constructor(e="javascript"){this.languages=new Map,x.forEach(n=>{this.languages.set(n.id,n)});const t=this.languages.get(e);if(!t)throw new Error(`Language "${e}" not found in config`);this.currentLanguage=t}getLanguage(e){return this.languages.get(e)}getAllLanguages(){return Array.from(this.languages.values())}switchLanguage(e){const t=this.languages.get(e);if(!t)throw new Error(`Language "${e}" not supported`);return this.currentLanguage=t,this.currentLanguage}getCurrentLanguage(){return this.currentLanguage}isSupported(e){return this.languages.has(e)}getRunnableLanguages(){return Array.from(this.languages.values()).filter(e=>e.canRun)}getTemplate(e,t,n){var a,s;if(n&&n[e]!==void 0&&n[e]!==null)return n[e];if(((a=t==null?void 0:t.languageTemplates)==null?void 0:a[e])!==void 0&&((s=t==null?void 0:t.languageTemplates)==null?void 0:s[e])!==null)return t.languageTemplates[e];const i=this.languages.get(e);return i&&i.fallbackTemplate?i.fallbackTemplate:""}}async function P(h,e){const t=performance.now();try{if(!e||e.length===0){const d=[],o={log:(...m)=>{d.push(m.map(v=>typeof v=="object"?JSON.stringify(v,null,2):String(v)).join(" "))},error:(...m)=>{d.push("ERROR: "+m.join(" "))},warn:(...m)=>{d.push("WARN: "+m.join(" "))}};new Function("console",h)(o);const g=performance.now()-t;return{output:d.join(`
|
|
149
|
+
`)||"(无输出)",executionTime:g,status:"success"}}const n=[],i=[],a=`
|
|
150
|
+
${h}
|
|
151
|
+
|
|
152
|
+
// 尝试找到入口函数
|
|
153
|
+
let mainFn = null;
|
|
154
|
+
// 优先级 1: solution 函数
|
|
155
|
+
if (typeof solution === 'function') mainFn = solution;
|
|
156
|
+
// 优先级 2: twoSum (针对示例)
|
|
157
|
+
else if (typeof twoSum === 'function') mainFn = twoSum;
|
|
158
|
+
// 优先级 3: 寻找最后一个定义的函数 (简单启发式,可能不准确)
|
|
159
|
+
|
|
160
|
+
if (!mainFn) {
|
|
161
|
+
// 如果没找到具名函数,尝试返回一个错误
|
|
162
|
+
throw new Error("未找到入口函数 (请定义 solution 或 twoSum 函数)");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return mainFn;
|
|
166
|
+
`;let s=(d,o)=>{const y=o.map(g=>typeof g=="object"?JSON.stringify(g,null,2):String(g)).join(" ");n.push(y)};const l={log:(...d)=>s("log",d),error:(...d)=>s("error",d),warn:(...d)=>s("warn",d)},c=new Function("console",a)(l);for(const d of e){const o=[],y=performance.now();let g="error",m,v;s=(b,w)=>{const T=w.map(k=>typeof k=="object"?JSON.stringify(k,null,2):String(k)).join(" ");o.push(T)};try{let b;Array.isArray(d.input)?b=c(...d.input):b=c(d.input),m=b;let w=!1;if(d.expected!==void 0)try{w=JSON.stringify(b)===JSON.stringify(d.expected)}catch{w=b===d.expected}else w=!0;g=w?"passed":"failed"}catch(b){g="error",v=b.message,m=void 0}const O=performance.now();i.push({id:d.id,status:g,input:d.input,output:m,expected:d.expected,log:o.join(`
|
|
167
|
+
`),error:v,executionTime:O-y})}const u=performance.now()-t,p=i.some(d=>d.status==="error"),f=i.some(d=>d.status==="failed");return{output:n.join(`
|
|
168
|
+
`),executionTime:u,status:p||f?"error":"success",testResults:i}}catch(n){const i=performance.now()-t;return{output:"",error:n.message||String(n),executionTime:i,status:"error"}}}async function z(h){const e=performance.now();try{return{output:"Python 运行功能需要加载 Pyodide (暂未实现)",executionTime:performance.now()-e,status:"error",error:"Pyodide 未加载"}}catch(t){return{output:"",error:t.message,executionTime:performance.now()-e,status:"error"}}}async function C(h,e){const t=performance.now();try{return{output:`${e} 远程运行功能需要配置编译服务 (暂未实现)`,executionTime:performance.now()-t,status:"error",error:"远程编译服务未配置"}}catch(n){return{output:"",error:n.message,executionTime:performance.now()-t,status:"error"}}}const V={javascript:P,typescript:P,python:z,java:h=>C(h,"Java"),cpp:h=>C(h,"C++"),go:h=>C(h,"Go")};function A(h){return V[h]}class j{constructor(e=5e3){this.abortController=null,this.timeout=e}async run(e,t,n){const i=A(t);if(!i)return{output:"",error:`语言 "${t}" 不支持运行`,executionTime:0,status:"error"};this.abortController=new AbortController;const a=setTimeout(()=>{var s;(s=this.abortController)==null||s.abort()},this.timeout);try{const s=await Promise.race([i(e,n),this.createTimeoutPromise()]);return clearTimeout(a),s}catch(s){return clearTimeout(a),s.name==="AbortError"?{output:"",error:`执行超时(${this.timeout}ms)`,executionTime:this.timeout,status:"timeout"}:{output:"",error:s.message||String(s),executionTime:0,status:"error"}}finally{this.abortController=null}}createTimeoutPromise(){return new Promise((e,t)=>{var n;(n=this.abortController)==null||n.signal.addEventListener("abort",()=>{const i=new Error("Execution timeout");i.name="AbortError",t(i)})})}cancel(){var e;(e=this.abortController)==null||e.abort()}setTimeout(e){this.timeout=e}destroy(){this.cancel()}}function R(h){return h.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function L(h){let e=h;return e=e.replace(/`([^`]+)`/g,"<code>$1</code>"),e=e.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),e=e.replace(/\*([^*]+)\*/g,"<em>$1</em>"),e=e.replace(/_([^_]+)_/g,"<em>$1</em>"),e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'),e}function D(h){const e=h||"",t=[];let n=e.replace(/```(?:[\w-]+)?\n([\s\S]*?)```/g,(c,u)=>{const p=R(u.trimEnd()),f=`@@CODEBLOCK_${t.length}@@`;return t.push(`<pre><code>${p}</code></pre>`),f});n=R(n);const i=n.split(/\r?\n/),a=[];let s=!1;const l=()=>{s&&(a.push("</ul>"),s=!1)};for(const c of i){const u=c.trim();if(!u){l();continue}const p=u.match(/^(#{1,6})\s+(.*)$/);if(p){l();const d=p[1].length;a.push(`<h${d}>${L(p[2])}</h${d}>`);continue}const f=u.match(/^[-*+]\s+(.*)$/);if(f){s||(a.push("<ul>"),s=!0),a.push(`<li>${L(f[1])}</li>`);continue}l(),a.push(`<p>${L(u)}</p>`)}l();let r=a.join(`
|
|
169
|
+
`);return t.forEach((c,u)=>{r=r.replace(`@@CODEBLOCK_${u}@@`,c)}),r}class q{constructor(e){if(this.monacoWrapper=null,this.layoutManager=null,this.initialized=!1,this._pendingLanguage=null,this._pendingValue=null,this.resizeObserver=null,this.loadingMask=null,this.toolbar=null,this.langSelect=null,this.markdownEditor=null,this.markdownPreview=null,this.testCases=[],this.id=`sce_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,this.options=e,typeof e.container=="string"){const t=document.querySelector(e.container);if(!t)throw new Error(`Container "${e.container}" not found`);this.container=t}else this.container=e.container;this.languageManager=new H(e.language||"javascript"),this.codeRunner=new j(e.runTimeout||5e3),this.init()}showLoading(){if(this.loadingMask)return;this.loadingMask=document.createElement("div"),this.loadingMask.className="sce-loading-mask",this.loadingMask.style.cssText=`
|
|
170
|
+
position: absolute;
|
|
171
|
+
top: 0;
|
|
172
|
+
left: 0;
|
|
173
|
+
width: 100%;
|
|
174
|
+
height: 100%;
|
|
175
|
+
background: ${this.options.theme==="vs-dark"?"#1e1e1e":"#ffffff"};
|
|
176
|
+
display: flex;
|
|
177
|
+
align-items: center;
|
|
178
|
+
justify-content: center;
|
|
179
|
+
z-index: 1000;
|
|
180
|
+
color: ${this.options.theme==="vs-dark"?"#d4d4d4":"#333333"};
|
|
181
|
+
font-size: 14px;
|
|
182
|
+
font-family: -apple-system, system-ui, sans-serif;
|
|
183
|
+
`;const e=document.createElement("div");e.className="sce-spinner",e.textContent="Loading...",this.loadingMask.appendChild(e),this.container.style.position="relative",this.container.appendChild(this.loadingMask)}hideLoading(){this.loadingMask&&this.loadingMask.parentNode&&(this.loadingMask.parentNode.removeChild(this.loadingMask),this.loadingMask=null)}createMarkdownPanel(e){const t=document.createElement("div");t.className="sce-question-markdown",t.style.display="flex",t.style.flexDirection="column",t.style.height="100%",t.style.minHeight="0",t.style.gap="12px",t.style.overflow="hidden";const n=e.editable!==!1,i=n&&e.showEditor!==!1,a=n?e.showPreview!==!1:!0,s=e.value||"";let l=null,r=null,c=null,u=null,p=null;const f=()=>{if(r&&u){const o=r.style.display!=="none";u.classList.toggle("active",o)}if(c&&p){const o=c.style.display!=="none";p.classList.toggle("active",o)}},d=o=>{r&&(r.style.display=o===r?"flex":"none"),c&&(c.style.display=o===c?"flex":"none"),f()};if(n&&i&&a){const o=document.createElement("div");o.className="sce-markdown-tabs",o.style.display="flex",o.style.gap="8px",u=document.createElement("button"),u.type="button",u.className="sce-markdown-tab active",u.textContent="编辑",p=document.createElement("button"),p.type="button",p.className="sce-markdown-tab active",p.textContent="预览",o.appendChild(u),o.appendChild(p),t.appendChild(o)}if(i){r=document.createElement("div"),r.className="sce-markdown-editor-section",r.style.display="flex",r.style.flexDirection="column",r.style.flex="1",r.style.minHeight="0";const o=document.createElement("textarea");o.className="sce-markdown-editor",o.value=s,o.placeholder=e.placeholder||"在此编辑 Markdown...",o.readOnly=e.editable===!1,o.style.width="100%",o.style.flex="1",o.style.minHeight="120px",o.style.resize="none",o.style.boxSizing="border-box",o.style.padding="10px",o.style.borderRadius="6px",o.style.fontFamily="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",o.style.fontSize="12px",o.style.lineHeight="1.5",r.appendChild(o),t.appendChild(r),this.markdownEditor=o;const y=M(g=>{l&&l(g),e.onChange&&e.onChange(g)},150);o.addEventListener("input",()=>{y(o.value)})}if(a){c=document.createElement("div"),c.className="sce-markdown-preview-section",c.style.display="flex",c.style.flexDirection="column",c.style.flex="1",c.style.minHeight="0";const o=document.createElement("div");o.className="sce-markdown-preview",o.style.flex="1",o.style.minHeight="0",o.style.overflow="auto",o.style.padding="10px",o.style.borderRadius="6px",o.style.fontFamily="-apple-system, system-ui, sans-serif",o.style.fontSize="13px",o.style.lineHeight="1.6",l=y=>{o.innerHTML=D(y)},l(s),c.appendChild(o),t.appendChild(c),this.markdownPreview=o}if(u&&p&&(u.addEventListener("click",()=>{d(r)}),p.addEventListener("click",()=>{d(c)}),d(r)),!i&&!a){const o=document.createElement("div");o.textContent="未启用 Markdown 编辑/预览",t.appendChild(o)}return t}async init(){var e;try{if(this.showLoading(),this.options.showQuestionPanel!==!1){if(this.layoutManager=new $(this.container,this.options.defaultSplitRatio||.5,this.options.theme||"vs-dark"),this.options.questionMarkdown){const r=this.createMarkdownPanel(this.options.questionMarkdown);this.layoutManager.setLeftContent(r),this.layoutManager.setTheme(this.options.theme||"vs-dark")}else this.options.questionContent&&this.layoutManager.setLeftContent(this.options.questionContent);const s=this.layoutManager.getRightContainer(),l=document.createElement("div");l.className="sce-monaco-container",l.style.flex="1",l.style.minHeight="0",l.style.overflow="hidden",l.style.position="relative",s.appendChild(l),this.monacoWrapper=new E(l)}else{this.container.style.display="flex",this.container.style.flexDirection="column";const s=document.createElement("div");s.className="sce-monaco-container",s.style.flex="1",s.style.minHeight="0",s.style.overflow="hidden",s.style.position="relative",this.container.appendChild(s),this.monacoWrapper=new E(s)}const t=this.languageManager.getCurrentLanguage(),n=this.options.value!==void 0&&this.options.value!==null?this.options.value:this.languageManager.getTemplate(t.id,this.options.questionConfig,this.options.languageTemplates);console.log("🎨 SmartCodeEditor 初始化:",{hasValue:this.options.value!==void 0,valueLength:(e=this.options.value)==null?void 0:e.length,hasQuestionConfig:!!this.options.questionConfig,hasLanguageTemplates:!!this.options.languageTemplates,initialValuePreview:(n==null?void 0:n.substring(0,50))+"..."}),await this.monacoWrapper.initialize({value:n,language:t.monacoId,theme:this.options.theme||"vs-dark",readOnly:this.options.readOnly||!1,automaticLayout:!1,suggestOnTriggerCharacters:this.options.suggestOnTriggerCharacters,quickSuggestions:this.options.quickSuggestions});const i=t.extensions?t.extensions[0]:"";this.monacoWrapper.updateModel(n,t.monacoId,i,this.id);const a=this.languageManager.getCurrentLanguage();if(a.id!==t.id){const s=a.extensions?a.extensions[0]:"";this.monacoWrapper.updateModel(this.getValue(),a.monacoId,s,this.id)}if(this._pendingValue!==null&&(this.monacoWrapper.setValue(this._pendingValue),this._pendingValue=null),this.options.onChange){const s=M(this.options.onChange,300);this.monacoWrapper.onDidChangeContent(s)}this.initialized=!0,this._pendingLanguage&&(this.setLanguage(this._pendingLanguage),this._pendingLanguage=null),this._pendingValue!==null&&(this.monacoWrapper.setValue(this._pendingValue),this._pendingValue=null),this.createToolbar(),typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(()=>{requestAnimationFrame(()=>{this.layout()})}),this.resizeObserver.observe(this.container)),this.layout()}catch(t){throw console.error("Failed to initialize SmartCodeEditor:",t),t}finally{this.hideLoading()}}createToolbar(){if(!this.monacoWrapper)return;const e=this.layoutManager?this.layoutManager.getRightContainer():this.container,t=document.createElement("div");this.toolbar=t,t.className="sce-toolbar";const n=this.options.theme==="vs-dark",i=n?"#2d2d30":"#fff",a=n?"#454545":"#f3f3f3";if(t.style.cssText=`
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: 12px;
|
|
187
|
+
padding: 8px 16px;
|
|
188
|
+
background: ${i};
|
|
189
|
+
border-bottom: 1px solid ${a};
|
|
190
|
+
transition: all 0.2s;
|
|
191
|
+
flex-shrink: 0;
|
|
192
|
+
`,this.options.enableLanguageSwitch!==!1){const s=this.createLanguageSelector();t.appendChild(s)}if(this.options.enableRun!==!1){const s=this.createRunButton();t.appendChild(s)}if(this.options.enableSubmit!==!1){const s=this.createSubmitButton();t.appendChild(s)}e.insertBefore(t,e.firstChild)}createLanguageSelector(){const e=document.createElement("div");e.style.display="flex",e.style.alignItems="center",e.style.gap="8px";const t=document.createElement("span");t.textContent="语言:",t.style.color=this.options.theme==="vs-dark"?"#ccc":"#666",t.style.fontSize="13px";const n=document.createElement("select");this.langSelect=n;const i=this.options.theme==="vs-dark",a=i?"#3c3c3c":"#ffffff",s=i?"#ccc":"#333",l=i?"#454545":"#ccc";n.style.cssText=`
|
|
193
|
+
padding: 4px 8px;
|
|
194
|
+
border: 1px solid ${l};
|
|
195
|
+
background: ${a};
|
|
196
|
+
color: ${s};
|
|
197
|
+
border-radius: 4px;
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
font-size: 13px;
|
|
200
|
+
`;let r=this.languageManager.getAllLanguages();return this.options.supportedLanguages&&this.options.supportedLanguages.length>0&&(r=r.filter(c=>this.options.supportedLanguages.includes(c.id))),r.forEach(c=>{const u=document.createElement("option");u.value=c.id,u.textContent=`${c.icon||""} ${c.name}`.trim(),c.id===this.languageManager.getCurrentLanguage().id&&(u.selected=!0),n.appendChild(u)}),n.addEventListener("change",()=>{this.setLanguage(n.value)}),e.appendChild(t),e.appendChild(n),e}createRunButton(){const e=document.createElement("button");return e.innerHTML="<span>▶</span> 运行",e.style.cssText=`
|
|
201
|
+
padding: 6px 16px;
|
|
202
|
+
border: none;
|
|
203
|
+
background: #0e639c;
|
|
204
|
+
color: white;
|
|
205
|
+
border-radius: 4px;
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
font-size: 13px;
|
|
208
|
+
font-weight: 500;
|
|
209
|
+
margin-left: auto;
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
gap: 6px;
|
|
213
|
+
transition: background 0.2s;
|
|
214
|
+
`,e.addEventListener("click",async()=>{const t=e.innerHTML;try{e.disabled=!0,e.style.background="#0e639c80",e.style.cursor="not-allowed",e.innerHTML='<span class="sce-btn-spinner"></span> 运行中...',await this.run()}finally{e.disabled=!1,e.style.background="#0e639c",e.style.cursor="pointer",e.innerHTML=t}}),e.addEventListener("mouseenter",()=>{e.disabled||(e.style.background="#1177bb")}),e.addEventListener("mouseleave",()=>{e.disabled||(e.style.background="#0e639c")}),this.injectSpinnerStyle(),e}createSubmitButton(){const e=document.createElement("button");return e.textContent="提交",e.title="提交代码进行评测",e.style.cssText=`
|
|
215
|
+
padding: 6px 16px;
|
|
216
|
+
border: none;
|
|
217
|
+
background: #4caf50;
|
|
218
|
+
color: white;
|
|
219
|
+
border-radius: 4px;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
font-size: 13px;
|
|
222
|
+
font-weight: 500;
|
|
223
|
+
margin-left: 8px;
|
|
224
|
+
display: flex;
|
|
225
|
+
align-items: center;
|
|
226
|
+
gap: 6px;
|
|
227
|
+
transition: background 0.2s;
|
|
228
|
+
`,e.addEventListener("click",async()=>{if(this.options.onSubmit){const t=e.textContent||"提交";try{e.disabled=!0,e.style.background="#4caf5080",e.style.cursor="not-allowed",e.innerHTML='<span class="sce-btn-spinner"></span> 提交中...',await this.options.onSubmit(this.getValue(),this.getLanguage())}finally{e.disabled=!1,e.style.background="#4caf50",e.style.cursor="pointer",e.textContent=t}}}),e.addEventListener("mouseenter",()=>{e.disabled||(e.style.background="#43a047")}),e.addEventListener("mouseleave",()=>{e.disabled||(e.style.background="#4caf50")}),e}injectSpinnerStyle(){if(document.getElementById("sce-btn-spinner-style"))return;const e=document.createElement("style");e.id="sce-btn-spinner-style",e.innerHTML=`
|
|
229
|
+
@keyframes sce-spin {
|
|
230
|
+
0% { transform: rotate(0deg); }
|
|
231
|
+
100% { transform: rotate(360deg); }
|
|
232
|
+
}
|
|
233
|
+
.sce-btn-spinner {
|
|
234
|
+
display: inline-block;
|
|
235
|
+
width: 12px;
|
|
236
|
+
height: 12px;
|
|
237
|
+
border: 2px solid rgba(255,255,255,0.3);
|
|
238
|
+
border-radius: 50%;
|
|
239
|
+
border-top-color: #fff;
|
|
240
|
+
animation: sce-spin 1s ease-in-out infinite;
|
|
241
|
+
}
|
|
242
|
+
`,document.head.appendChild(e)}getValue(){var e;return((e=this.monacoWrapper)==null?void 0:e.getValue())||""}setValue(e){if(!this.monacoWrapper||!this.initialized){this._pendingValue=e;return}this.monacoWrapper.setValue(e)}getLanguage(){return this.languageManager.getCurrentLanguage().id}setLanguage(e){var s;if(!this.monacoWrapper||!this.initialized){this._pendingLanguage=e;return}const t=this.languageManager.switchLanguage(e),n=this.getValue(),i=t.extensions?t.extensions[0]:"";(s=this.monacoWrapper)==null||s.updateModel(n,t.monacoId,i,this.id);const a=this.languageManager.getTemplate(e,this.options.questionConfig,this.options.languageTemplates);this.setValue(a),this.options.onLanguageChange&&this.options.onLanguageChange(e)}getSupportedLanguages(){return this.languageManager.getAllLanguages()}setTheme(e){var t,n;if((t=this.monacoWrapper)==null||t.setTheme(e),(n=this.layoutManager)==null||n.setTheme(e),this.options.theme=e,this.toolbar){const i=e==="vs-dark";this.toolbar.style.background=i?"#2d2d30":"#f3f3f3",this.toolbar.style.borderBottom=i?"1px solid #454545":"1px solid #e0e0e0"}if(this.langSelect){const i=e==="vs-dark";this.langSelect.style.background=i?"#3c3c3c":"#ffffff",this.langSelect.style.color=i?"#ccc":"#333",this.langSelect.style.borderColor=i?"#454545":"#ccc",this.langSelect.previousElementSibling instanceof HTMLElement&&(this.langSelect.previousElementSibling.style.color=i?"#ccc":"#666")}}getTheme(){return this.options.theme||"vs-dark"}setQuestionContent(e){var t;(t=this.layoutManager)==null||t.setLeftContent(e),this.markdownEditor=null,this.markdownPreview=null}setQuestionMarkdown(e,t){if(!this.layoutManager)return;const n={...this.options.questionMarkdown||{},...t||{},value:e},i=this.createMarkdownPanel(n);this.layoutManager.setLeftContent(i),this.options.questionMarkdown=n,this.layoutManager.setTheme(this.options.theme||"vs-dark")}showQuestionPanel(){var e;(e=this.layoutManager)==null||e.setQuestionPanelVisible(!0)}hideQuestionPanel(){var e;(e=this.layoutManager)==null||e.setQuestionPanelVisible(!1)}setTestCases(e){this.testCases=e}async run(e){const t=this.getValue(),n=this.getLanguage(),i=this.languageManager.getCurrentLanguage();if(!i.canRun){const a={output:"",error:`语言 "${i.name}" 不支持运行`,executionTime:0,status:"error"};return this.options.onRun&&this.options.onRun(a),a}if(this.options.customRunner){const a=e||this.testCases;try{const s=await this.options.customRunner(t,n,a);return this.options.onRun&&this.options.onRun(s),s}catch(s){const l={output:"",error:s.message||"自定义运行器执行失败",executionTime:0,status:"error"};return this.options.onRun&&this.options.onRun(l),l}}try{const a=e||this.testCases,s=await this.codeRunner.run(t,n,a);return this.options.onRun&&this.options.onRun(s),s}catch(a){const s={output:"",error:a.message,executionTime:0,status:"error"};return this.options.onRun&&this.options.onRun(s),s}}cancelRun(){this.codeRunner.cancel()}resize(){var e;(e=this.monacoWrapper)==null||e.layout()}setSplitRatio(e){var t,n;(t=this.layoutManager)==null||t.setSplitRatio(e),(n=this.monacoWrapper)==null||n.layout()}layout(){var e;(e=this.monacoWrapper)==null||e.layout()}updateConfig(e){var n;const t={};e.questionConfig&&(this.options.questionConfig=e.questionConfig),e.languageTemplates&&(this.options.languageTemplates=e.languageTemplates),e.supportedLanguages&&(this.options.supportedLanguages=e.supportedLanguages,this.refreshLanguageSelector()),e.suggestOnTriggerCharacters!==void 0&&(this.options.suggestOnTriggerCharacters=e.suggestOnTriggerCharacters,t.suggestOnTriggerCharacters=e.suggestOnTriggerCharacters),e.quickSuggestions!==void 0&&(this.options.quickSuggestions=e.quickSuggestions,t.quickSuggestions=e.quickSuggestions),Object.keys(t).length>0&&((n=this.monacoWrapper)==null||n.updateOptions(t))}refreshLanguageSelector(){if(!this.langSelect)return;this.langSelect.innerHTML="";let e=this.languageManager.getAllLanguages();this.options.supportedLanguages&&this.options.supportedLanguages.length>0&&(e=e.filter(t=>this.options.supportedLanguages.includes(t.id))),e.forEach(t=>{const n=document.createElement("option");n.value=t.id,n.textContent=`${t.icon||""} ${t.name}`.trim(),t.id===this.languageManager.getCurrentLanguage().id&&(n.selected=!0),this.langSelect.appendChild(n)})}destroy(){var e,t,n;(e=this.resizeObserver)==null||e.disconnect(),(t=this.monacoWrapper)==null||t.dispose(),(n=this.layoutManager)==null||n.destroy(),this.codeRunner.destroy()}}const S={light:{id:"vs",name:"VS Light",displayName:"浅色主题"},dark:{id:"vs-dark",name:"VS Dark",displayName:"深色主题"},"high-contrast":{id:"hc-black",name:"High Contrast",displayName:"高对比度"}};function F(){return Object.values(S)}function U(h){return S[h]}exports.LANGUAGE_CONFIGS=x;exports.SmartCodeEditor=q;exports.THEME_CONFIGS=S;exports.getAllLanguages=W;exports.getAllThemes=F;exports.getLanguageConfig=N;exports.getThemeConfig=U;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SmartCodeEditor } from './core/SmartCodeEditor';
|
|
2
|
+
export type { SmartCodeEditorOptions, LanguageConfig, RunResult, RunnerStrategy, MonacoEditorOptions, } from './types';
|
|
3
|
+
export { LANGUAGE_CONFIGS, getAllLanguages, getLanguageConfig, } from './config/languages';
|
|
4
|
+
export { THEME_CONFIGS, getAllThemes, getThemeConfig } from './config/themes';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,cAAc,EACd,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
|