From 6cb7d5d8b730c2e50b2bcb64b066739bda921369 Mon Sep 17 00:00:00 2001 From: Rizky Date: Sat, 25 Nov 2023 01:09:10 +0700 Subject: [PATCH] wip fix --- app/web/src/nova/ed/logic/tree/sync-walk.tsx | 5 +- .../src/nova/ed/panel/popup/script/monaco.tsx | 105 +++++++++++++----- .../src/nova/ed/panel/popup/script/scope.tsx | 22 ++-- .../nova/ed/panel/tree/node/item/action.tsx | 78 ++++++------- .../editor/panel/script/monaco/mount.tsx | 23 ++-- app/web/src/utils/script/mount.tsx | 11 +- 6 files changed, 158 insertions(+), 86 deletions(-) diff --git a/app/web/src/nova/ed/logic/tree/sync-walk.tsx b/app/web/src/nova/ed/logic/tree/sync-walk.tsx index e3f4c8b4..ec978191 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -144,9 +144,10 @@ export const syncWalkMap = ( mitem_comp.set("ref_ids", new Y.Map() as any); ref_ids = {}; } - const original_id = item.id; + const old_id = item.id; mapItem(mcomp, item); - item.id = original_id; + item.originalId = item.id; + item.id = old_id; const meta: EdMeta = { item, diff --git a/app/web/src/nova/ed/panel/popup/script/monaco.tsx b/app/web/src/nova/ed/panel/popup/script/monaco.tsx index dab98b28..62d8f461 100644 --- a/app/web/src/nova/ed/panel/popup/script/monaco.tsx +++ b/app/web/src/nova/ed/panel/popup/script/monaco.tsx @@ -1,19 +1,20 @@ -import type { OnMount } from "@monaco-editor/react"; +import type { Monaco, OnMount } from "@monaco-editor/react"; import { createStore } from "idb-keyval"; import trim from "lodash.trim"; import { useGlobal, useLocal } from "web-utils"; import { jscript } from "../../../../../utils/script/jscript"; import { jsMount } from "../../../../../utils/script/mount"; import { monacoTypings } from "../../../../../utils/script/typings"; -import { EDGlobal, active } from "../../../logic/ed-global"; +import { EDGlobal, ISingleScope, active } from "../../../logic/ed-global"; import { declareScope } from "./scope"; +import { useEffect } from "react"; export type MonacoEditor = Parameters[0]; export const ScriptMonaco = () => { const p = useGlobal(EDGlobal, "EDITOR"); const local = useLocal({ editor: null as null | MonacoEditor, - reloading: false, + monaco: null as null | Monaco, changeTimeout: 0 as any, historyOpen: false, idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"), @@ -23,10 +24,44 @@ export const ScriptMonaco = () => { if (!Editor) return null; let meta = p.page.meta[active.item_id]; - if (active.comp_id) { + if (active.comp_id && p.comp.list[active.comp_id]) { meta = p.comp.list[active.comp_id].meta[active.item_id]; } + useEffect(() => { + if (local.monaco && local.editor) { + const val: string = ( + typeof adv[p.ui.popup.script.mode] === "string" + ? adv[p.ui.popup.script.mode] + : "" + ) as any; + local.monaco.editor.getModels().forEach((model) => { + const uri = model.uri.toString(); + if ( + uri.startsWith("inmemory://model") || + uri.startsWith("ts:comp-") || + uri.startsWith("ts:page-") + ) { + model.dispose(); + } + }); + + let model = local.monaco.editor.createModel( + val, + "typescript", + local.monaco.Uri.parse( + `ts:${ + active.comp_id ? `comp-${active.comp_id}` : `page-${p.page.cur.id}` + }-${active.item_id}.tsx` + ) + ); + local.editor.setModel(model); + declareScope(p, local.editor, local.monaco).then(() => { + local.render(); + }); + } + }, [active.item_id]); + if (!meta) return null; const item = meta.item; @@ -120,35 +155,47 @@ export const ScriptMonaco = () => { ) ); editor.setModel(model); - } - monaco.editor.registerEditorOpener({ - openCodeEditor(source, r, selectionOrPosition) { - const path = r.path.split("~"); - const id = path[path.length - 1].replace(".d.ts", ""); - const meta = p.page.meta[id]; + monaco.editor.registerEditorOpener({ + openCodeEditor(source, r, selectionOrPosition) { + const cpath = r.path.substring(`scope~`.length).split("__"); + const comp_id = cpath[0]; + const path = cpath[1].split("~"); + const type = path[0] as "prop" | "passprop" | "local"; + const id = path[path.length - 1].replace(".d.ts", ""); - if (meta) { - console.log(meta.item, meta); - } + if (comp_id) { + let meta = p.page.meta[id]; + if (active.comp_id) { + meta = p.comp.list[active.comp_id].meta[id]; + } - // https://github.com/microsoft/vscode/pull/177064#issue-1623100628 - return false; - }, - }); + if (meta && meta.item.originalId) { + active.item_id = meta.item.originalId; + } + active.comp_id = comp_id; + } else { + active.item_id = id; + } + p.render(); - await jsMount(editor, monaco); - await monacoTypings( - { - site_dts: p.site_dts, - script: { - siteTypes: {}, + return false; }, - site: p.site.config, - }, - monaco, - { types: {}, values: {} } - ); - await declareScope(p, editor, monaco); + }); + + await jsMount(editor, monaco); + await monacoTypings( + { + site_dts: p.site_dts, + script: { + siteTypes: {}, + }, + site: p.site.config, + }, + monaco, + { types: {}, values: {} } + ); + await declareScope(p, editor, monaco); + } }} /> ); diff --git a/app/web/src/nova/ed/panel/popup/script/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope.tsx index dff221a7..9281246f 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope.tsx @@ -12,10 +12,12 @@ export const declareScope = async ( let active_id = active.item_id; let s = deepClone(p.page.scope[active_id]); - if (active.comp_id) { + if (active.comp_id && p.comp.list[active.comp_id]) { s = deepClone(p.comp.list[active.comp_id].scope[active.item_id]); } + if (!s) return; + monaco.editor.getModels().forEach((model) => { if (model.uri.toString().startsWith("ts:scope~")) { model.dispose(); @@ -44,7 +46,7 @@ export const declareScope = async ( if (arg.type !== "local") { addScope( monaco, - `${arg.type}~${arg.name}`, + `${arg.comp_id || ""}__${arg.type}~${arg.name}~${arg.id}`, `\ export const {}; declare global { @@ -54,7 +56,7 @@ declare global { } else { addScope( monaco, - `${arg.type}~${arg.id}`, + `${arg.comp_id || ""}__${arg.type}~${arg.id}`, `\ export const {}; const __val = ${arg.value}; @@ -75,13 +77,15 @@ type IEachArgScope = { id: string; type: "local" | "prop" | "passprop"; index?: number; - isProp?: boolean; + is_prop?: boolean; + comp_id?: string; }; const spreadScope = ( p: PG, - s: ISingleScope, + s: ISingleScope | undefined, each: (arg: IEachArgScope) => void ) => { + if (!s) return; const parents = [...s.p]; const layout_id = p.site.layout.id; let layout = null as null | EPage; @@ -122,7 +126,7 @@ const spreadScope = ( if (!item) { if (comp_id) { item = p.comp.list[comp_id].scope[parent_id]; - } else if (active.comp_id) { + } else if (active.comp_id && p.comp.list[active.comp_id]) { item = p.comp.list[active.comp_id].scope[parent_id]; } else { item = p.page.scope[parent_id]; @@ -131,6 +135,7 @@ const spreadScope = ( if (item) { if (item.c) { + comp_id = item.c; mergeScopes(item.p, each, item.c); } @@ -139,6 +144,7 @@ const spreadScope = ( if (scope.local) each({ s, + comp_id, type: "local", id: parent_id, name: scope.local.name, @@ -150,6 +156,7 @@ const spreadScope = ( for (const [k, v] of Object.entries(scope.passprop)) { each({ s, + comp_id, type: "passprop", id: parent_id, name: k, @@ -163,11 +170,12 @@ const spreadScope = ( for (const [k, v] of Object.entries(scope.props)) { each({ s, + comp_id, type: "prop", id: parent_id, name: k, value: v.value, - isProp: true, + is_prop: true, }); } } diff --git a/app/web/src/nova/ed/panel/tree/node/item/action.tsx b/app/web/src/nova/ed/panel/tree/node/item/action.tsx index 82a1cf77..79d3a807 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action.tsx @@ -24,7 +24,45 @@ export const EdTreeAction = ({ if (!mode && item.adv?.html) mode = "html"; return ( -
+
+ {(!comp.enabled || (comp.enabled && comp.id === active.comp_id)) && ( + { + p.ui.popup.script.open = true; + p.ui.popup.script.mode = (mode || "js") as any; + p.render(); + }} + > +
`, + }} + >
+
+ )} + {comp.enabled && ( <> {comp.id !== active.comp_id && ( @@ -78,44 +116,6 @@ export const EdTreeAction = ({ )} )} - - {!comp.enabled && ( - { - p.ui.popup.script.open = true; - p.ui.popup.script.mode = (mode || "js") as any; - p.render(); - }} - > -
`, - }} - >
-
- )}
); }; diff --git a/app/web/src/render/editor/panel/script/monaco/mount.tsx b/app/web/src/render/editor/panel/script/monaco/mount.tsx index ac538e83..cf906271 100644 --- a/app/web/src/render/editor/panel/script/monaco/mount.tsx +++ b/app/web/src/render/editor/panel/script/monaco/mount.tsx @@ -41,13 +41,22 @@ export const jsMount = async (p: PG, editor: MonacoEditor, monaco: Monaco) => { }; const jsxHgController = new MonacoJsxSyntaxHighlight(getWorker(), monaco); - const { highlighter } = jsxHgController.highlighterBuilder({ - editor: editor, - }); - highlighter(); - editor.onDidChangeModelContent(() => { - highlighter(); - }); + try { + const { highlighter } = jsxHgController.highlighterBuilder({ + editor: editor, + }); + + if (typeof editor.getModel === "function") { + highlighter(); + } + editor.onDidChangeModelContent(() => { + if (typeof editor.getModel === "function") { + try { + highlighter(); + } catch (e) {} + } + }); + } catch (e) {} monaco.languages.registerDocumentFormattingEditProvider("typescript", { async provideDocumentFormattingEdits(model, options, token) { diff --git a/app/web/src/utils/script/mount.tsx b/app/web/src/utils/script/mount.tsx index 3eb7ae28..889f8dac 100644 --- a/app/web/src/utils/script/mount.tsx +++ b/app/web/src/utils/script/mount.tsx @@ -143,9 +143,16 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco) => { const { highlighter } = jsxHgController.highlighterBuilder({ editor: editor, }); - highlighter(); - editor.onDidChangeModelContent(() => { + + if (typeof editor.getModel === "function") { highlighter(); + } + editor.onDidChangeModelContent(() => { + if (typeof editor.getModel === "function") { + try { + highlighter(); + } catch (e) {} + } }); }