Skip to content

Commit f94481c

Browse files
committed
fix monaco editor
1 parent 2a6bc45 commit f94481c

File tree

5 files changed

+142
-78
lines changed

5 files changed

+142
-78
lines changed

_patchAndMinifyMonaco.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import * as esbuild from 'esbuild';
2+
import fs from 'fs';
3+
import path from 'path';
4+
5+
const monacoEsm = './node_modules/monaco-editor/esm';
6+
const outDir = `${monacoEsm}/vs/editor`;
7+
const absOutDir = path.resolve(outDir);
8+
9+
// --- Patch: remove CSS imports (esbuild can't handle them) ---
10+
function walkDir(dir, callback) {
11+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
12+
const full = path.join(dir, entry.name);
13+
if (entry.isDirectory()) {
14+
walkDir(full, callback);
15+
} else if (entry.isFile() && full.endsWith('.js')) {
16+
callback(full);
17+
}
18+
}
19+
}
20+
21+
function removeCssImports(filePath) {
22+
const original = fs.readFileSync(filePath, 'utf8');
23+
const content = original.replace(/^\s*import\s+[^;]*['"]([^'"]+\.css)['"]\s*;?\s*$/gm, '');
24+
if (content !== original) {
25+
fs.writeFileSync(filePath, content, 'utf8');
26+
console.log('Cleaned:', filePath);
27+
}
28+
}
29+
30+
walkDir(path.resolve(monacoEsm), removeCssImports);
31+
fs.rmSync('./node_modules/monaco-editor/dev', { recursive: true, force: true });
32+
33+
// --- Patch: fix shadow DOM mouse event handling ---
34+
const mouseHandlerPath = `${monacoEsm}/vs/editor/browser/controller/mouseHandler.js`;
35+
const mouseHandlerCode = fs.readFileSync(mouseHandlerPath, 'utf8');
36+
const patchedMouseHandler = mouseHandlerCode.replace(
37+
/this\.viewHelper\.viewDomNode\.contains\(e\.target\)/,
38+
'this.viewHelper.viewDomNode.contains(e.composedPath()[0])'
39+
);
40+
if (patchedMouseHandler !== mouseHandlerCode) {
41+
fs.writeFileSync(mouseHandlerPath, patchedMouseHandler);
42+
console.log('Patched monaco editor mouseHandler');
43+
}
44+
45+
// --- Bundle: main editor ---
46+
await esbuild.build({
47+
entryPoints: [`${monacoEsm}/vs/editor/editor.main.js`],
48+
outdir: outDir,
49+
entryNames: 'editor.main.min',
50+
bundle: true,
51+
minify: true,
52+
splitting: true,
53+
format: 'esm',
54+
platform: 'neutral',
55+
external: ['dompurify'],
56+
}).catch(() => process.exit(1));
57+
58+
// --- Bundle: language workers ---
59+
// Find all *.worker.js files outside outDir and bundle them there so that
60+
// import.meta.url-relative paths in the split chunks resolve correctly.
61+
function findWorkers(dir) {
62+
const workers = [];
63+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
64+
const full = path.join(dir, entry.name);
65+
if (entry.isDirectory()) {
66+
workers.push(...findWorkers(full));
67+
} else if (entry.isFile() && entry.name.endsWith('.worker.js') && path.resolve(dir) !== absOutDir) {
68+
workers.push(full);
69+
}
70+
}
71+
return workers;
72+
}
73+
74+
const workerFiles = findWorkers(monacoEsm);
75+
console.log(`Bundling ${workerFiles.length} worker(s) into ${outDir}`);
76+
77+
for (const workerFile of workerFiles) {
78+
const name = path.basename(workerFile, '.js');
79+
await esbuild.build({
80+
entryPoints: [workerFile],
81+
outdir: outDir,
82+
entryNames: name,
83+
bundle: true,
84+
format: 'esm',
85+
platform: 'neutral',
86+
external: ['dompurify'],
87+
allowOverwrite: true,
88+
}).catch(() => process.exit(1));
89+
}

index.html

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,23 @@
1919
<script>
2020
const importMap = {
2121
imports: {
22-
"aa__monaco-editor": "./node_modules/monaco-editor/esm/vs/editor/editor.main.min.js",
23-
"aa__@node-projects/base-custom-webcomponent": "./node_modules/@node-projects/base-custom-webcomponent/dist/index-min.js",
24-
"aa__@node-projects/css-parser": "./node_modules/@node-projects/css-parser/dist/index-min.js",
25-
"aa__@node-projects/web-component-designer": "./node_modules/@node-projects/web-component-designer/dist/index-min.js",
26-
"aa__@node-projects/web-component-designer-widgets-wunderbaum": "./node_modules/@node-projects/web-component-designer-widgets-wunderbaum/dist/index-min.js",
27-
"aa__@node-projects/lean-he-esm": "./node_modules/@node-projects/lean-he-esm/lib/index-min.js",
28-
"aa__@node-projects/node-html-parser-esm": "./node_modules/@node-projects/node-html-parser-esm/dist/index-min.js",
29-
"aa__dock-spawn-ts": "./node_modules/dock-spawn-ts/lib/js/index-webcomponent-min.js",
30-
31-
"monaco-editor": "./node_modules/monaco-editor/esm/vs/editor/editor.main.js",
32-
"@node-projects/base-custom-webcomponent": "./node_modules/@node-projects/base-custom-webcomponent/dist/index.js",
33-
"@node-projects/css-parser": "./node_modules/@node-projects/css-parser/dist/index.js",
34-
"@node-projects/web-component-designer": "./node_modules/@node-projects/web-component-designer/dist/index.js",
35-
"@node-projects/web-component-designer-widgets-wunderbaum": "./node_modules/@node-projects/web-component-designer-widgets-wunderbaum/dist/index.js",
36-
"@node-projects/lean-he-esm": "./node_modules/@node-projects/lean-he-esm/lib/index.js",
37-
"@node-projects/node-html-parser-esm": "./node_modules/@node-projects/node-html-parser-esm/dist/index.js",
38-
"dock-spawn-ts": "./node_modules/dock-spawn-ts/lib/js/index-webcomponent.js",
22+
"monaco-editor": "./node_modules/monaco-editor/esm/vs/editor/editor.main.min.js",
23+
"@node-projects/base-custom-webcomponent": "./node_modules/@node-projects/base-custom-webcomponent/dist/index-min.js",
24+
"@node-projects/css-parser": "./node_modules/@node-projects/css-parser/dist/index-min.js",
25+
"@node-projects/web-component-designer": "./node_modules/@node-projects/web-component-designer/dist/index-min.js",
26+
"@node-projects/web-component-designer-widgets-wunderbaum": "./node_modules/@node-projects/web-component-designer-widgets-wunderbaum/dist/index-min.js",
27+
"@node-projects/lean-he-esm": "./node_modules/@node-projects/lean-he-esm/lib/index-min.js",
28+
"@node-projects/node-html-parser-esm": "./node_modules/@node-projects/node-html-parser-esm/dist/index-min.js",
29+
"dock-spawn-ts": "./node_modules/dock-spawn-ts/lib/js/index-webcomponent-min.js",
30+
31+
"max__monaco-editor": "./node_modules/monaco-editor/esm/vs/editor/editor.main.js",
32+
"max__@node-projects/base-custom-webcomponent": "./node_modules/@node-projects/base-custom-webcomponent/dist/index.js",
33+
"max__@node-projects/css-parser": "./node_modules/@node-projects/css-parser/dist/index.js",
34+
"max__@node-projects/web-component-designer": "./node_modules/@node-projects/web-component-designer/dist/index.js",
35+
"max__@node-projects/web-component-designer-widgets-wunderbaum": "./node_modules/@node-projects/web-component-designer-widgets-wunderbaum/dist/index.js",
36+
"max__@node-projects/lean-he-esm": "./node_modules/@node-projects/lean-he-esm/lib/index.js",
37+
"max__@node-projects/node-html-parser-esm": "./node_modules/@node-projects/node-html-parser-esm/dist/index.js",
38+
"max__dock-spawn-ts": "./node_modules/dock-spawn-ts/lib/js/index-webcomponent.js",
3939

4040
"@mlc-ai/web-llm": "./node_modules/@mlc-ai/web-llm/lib/index.js",
4141
"@node-projects/": "./node_modules/@node-projects/",

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
"start": "web-dev-server --open",
99
"build": "tsc",
1010
"linkAll": "npm link @node-projects/web-component-designer @node-projects/web-component-designer-codeview-monaco @node-projects/web-component-designer-htmlparserservice-nodehtmlparser @node-projects/web-component-designer-stylesheetservice-css-parser @node-projects/web-component-designer-widgets-wunderbaum",
11-
"patchMonaco": "node patchMonaco",
12-
"bundleMonaco": "esbuild ./node_modules/monaco-editor/esm/vs/editor/editor.main.js --format=esm --minify --external:dompurify --platform=neutral --bundle --outfile=./node_modules/monaco-editor/esm/vs/editor/editor.main.min.js",
13-
"postinstall": "npm run patchMonaco && npm run bundleMonaco"
11+
"bundleMonaco": "node _patchAndMinifyMonaco.js",
12+
"postinstall": "npm run bundleMonaco"
1413
},
1514
"repository": {
1615
"type": "git",

patchMonaco.js

Lines changed: 0 additions & 49 deletions
This file was deleted.

src/appShell.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createDefaultServiceContainer, MiniatureView, NpmPackageLoader, BaseCustomWebcomponentBindingsService, JsonFileElementsService, DocumentContainer, CopyPasteAsJsonService, DebugView, UnkownElementsPropertiesService, sleep, RefactorView, BindingsRefactorService, TextRefactorService, SeperatorContextMenu, IDesignItem, DomConverter, PropertyGridWithHeader, DesignItem, ValueType, ObservedCustomElementsRegistry, IElementsJson, PreDefinedElementsService } from '@node-projects/web-component-designer';
2+
import type * as webllmType from "@mlc-ai/web-llm";
23

34
import { NodeHtmlParserService } from '@node-projects/web-component-designer-htmlparserservice-nodehtmlparser';
45
import { CodeViewMonaco } from '@node-projects/web-component-designer-codeview-monaco';
@@ -7,13 +8,6 @@ import { CssParserStylesheetService } from '@node-projects/web-component-designe
78
import '@node-projects/web-component-designer-widgets-wunderbaum';
89
import { PaletteTreeView, BindableObjectsBrowser, TreeViewExtended, ExpandCollapseContextMenu } from '@node-projects/web-component-designer-widgets-wunderbaum';
910

10-
import * as webllm from "@mlc-ai/web-llm";
11-
type EditResult = {
12-
answer: string;
13-
html: string;
14-
css: string;
15-
};
16-
1711
let serviceContainer = createDefaultServiceContainer();
1812
serviceContainer.register("bindingService", new BaseCustomWebcomponentBindingsService());
1913
let rootDir = "/web-component-designer-demo";
@@ -26,6 +20,30 @@ serviceContainer.registerLast("propertyService", new UnkownElementsPropertiesSer
2620
serviceContainer.register("refactorService", new BindingsRefactorService());
2721
serviceContainer.register("refactorService", new TextRefactorService());
2822

23+
/*
24+
globalThis.MonacoEnvironment = {
25+
getWorker: (_moduleId, label) => {
26+
switch (label) {
27+
case 'json':
28+
return new Worker(new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url), { type: 'module' });
29+
case 'css':
30+
case 'scss':
31+
case 'less':
32+
return new Worker(new URL('monaco-editor/esm/vs/language/css/css.worker', import.meta.url), { type: 'module' });
33+
case 'html':
34+
case 'handlebars':
35+
case 'razor':
36+
return new Worker(new URL('monaco-editor/esm/vs/language/html/html.worker', import.meta.url), { type: 'module' });
37+
case 'typescript':
38+
case 'javascript':
39+
return new Worker(new URL('monaco-editor/esm/vs/language/typescript/ts.worker', import.meta.url), { type: 'module' });
40+
default:
41+
return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url), { type: 'module' });
42+
}
43+
}
44+
};
45+
*/
46+
2947
serviceContainer.config.codeViewWidget = CodeViewMonaco;
3048

3149
serviceContainer.designerContextMenuExtensions.push(new ExpandCollapseContextMenu());
@@ -512,7 +530,7 @@ export class AppShell extends BaseCustomWebComponentConstructorAppend {
512530
nd.parent.container.setActiveChild(nd.container);
513531
}
514532

515-
engine: webllm.MLCEngine;
533+
engine: webllmType.MLCEngine;
516534
async LLM() {
517535
let op = this._getDomElement<HTMLTextAreaElement>('llmOutput');
518536
let btn = this._getDomElement<HTMLTextAreaElement>('llmEnable');
@@ -522,6 +540,8 @@ export class AppShell extends BaseCustomWebComponentConstructorAppend {
522540
}
523541
}
524542
async initLLM() {
543+
const webllm: typeof webllmType = await import("@mlc-ai/web-llm");
544+
525545
let op = this._getDomElement<HTMLTextAreaElement>('llmOutput');
526546
// Initialize with a progress callback
527547
const initProgressCallback = (progress) => {
@@ -575,11 +595,16 @@ export class AppShell extends BaseCustomWebComponentConstructorAppend {
575595
});
576596
}
577597

598+
578599
async editHtmlCss(
579600
prompt: string,
580601
html: string,
581602
css: string
582-
): Promise<EditResult> {
603+
): Promise<{
604+
answer: string;
605+
html: string;
606+
css: string;
607+
}> {
583608

584609
const systemPrompt = `
585610
You are an expert HTML and CSS editor inside a visual designer tool.

0 commit comments

Comments
 (0)