wip fix tree-rebuild
This commit is contained in:
parent
8188589065
commit
3c25a62192
|
|
@ -12,7 +12,6 @@ export const comp_load: SAction["comp"]["load"] = async function (
|
||||||
) {
|
) {
|
||||||
const result: Record<string, IScopeComp> = {};
|
const result: Record<string, IScopeComp> = {};
|
||||||
for (const id of ids) {
|
for (const id of ids) {
|
||||||
const root = await loadComponent(id, this);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { GenMetaP } from "../../../../web/src/nova/vi/utils/types";
|
||||||
import { IItem } from "../../../../web/src/utils/types/item";
|
import { IItem } from "../../../../web/src/utils/types/item";
|
||||||
import { DPage } from "../../../../web/src/utils/types/root";
|
import { DPage } from "../../../../web/src/utils/types/root";
|
||||||
import { SAction } from "../actions";
|
import { SAction } from "../actions";
|
||||||
import { loadComponent } from "../editor/load-component";
|
import { loadComponent, userSyncComponent } from "../editor/load-component";
|
||||||
import { parseJs } from "../editor/parser/parse-js";
|
import { parseJs } from "../editor/parser/parse-js";
|
||||||
import { activity } from "../entity/activity";
|
import { activity } from "../entity/activity";
|
||||||
import { conns } from "../entity/conn";
|
import { conns } from "../entity/conn";
|
||||||
|
|
@ -201,6 +201,8 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
await loading[id];
|
await loading[id];
|
||||||
|
} else {
|
||||||
|
userSyncComponent(sync, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (docs.comp[id]) {
|
if (docs.comp[id]) {
|
||||||
|
|
@ -239,6 +241,6 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => {
|
||||||
comps[id] = { id, snapshot: await gzipAsync(snap.bin) };
|
comps[id] = { id, snapshot: await gzipAsync(snap.bin) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { meta: simplifyMeta(meta), comps, entry };
|
return { meta: simplifyMeta(meta), comps, entry };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ import { gzipAsync } from "../entity/zlib";
|
||||||
import { sendWS } from "../sync-handler";
|
import { sendWS } from "../sync-handler";
|
||||||
import { SyncConnection, SyncType } from "../type";
|
import { SyncConnection, SyncType } from "../type";
|
||||||
|
|
||||||
export const loadComponent = async (id: string, sync: SyncConnection) => {
|
export const loadComponent = async (comp_id: string, sync: SyncConnection) => {
|
||||||
let snap = snapshot.get("comp", id);
|
let snap = snapshot.get("comp", comp_id);
|
||||||
let ydoc = docs.comp[id];
|
let ydoc = docs.comp[comp_id];
|
||||||
const conf = sync.conf;
|
const conf = sync.conf;
|
||||||
|
|
||||||
if (!conf) return undefined;
|
if (!conf) return undefined;
|
||||||
|
|
||||||
const createUndoManager = async (root: Y.Map<any>) => {
|
const createUndoManager = async (root: Y.Map<any>) => {
|
||||||
|
|
@ -21,25 +22,28 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const attachOnUpdate = async (doc: Y.Doc, um: Y.UndoManager) => {
|
const attachOnUpdate = async (doc: Y.Doc, um: Y.UndoManager) => {
|
||||||
snapshot.set("comp", id, "id_doc", um.doc.clientID);
|
snapshot.set("comp", comp_id, "id_doc", um.doc.clientID);
|
||||||
|
|
||||||
doc.on("update", async (update: Uint8Array, origin: any) => {
|
doc.on("update", async (update: Uint8Array, origin: any) => {
|
||||||
const bin = Y.encodeStateAsUpdate(doc);
|
const bin = Y.encodeStateAsUpdate(doc);
|
||||||
snapshot.set("comp", id, "bin", bin);
|
snapshot.set("comp", comp_id, "bin", bin);
|
||||||
|
|
||||||
const sv_local = await gzipAsync(update);
|
const sv_local = await gzipAsync(update);
|
||||||
|
|
||||||
const all = user.active.findAll({ comp_id: id });
|
const all = user.active.findAll({ comp_id: comp_id });
|
||||||
|
|
||||||
all.map((e) => {
|
all.map((e) => {
|
||||||
if (origin !== um) {
|
if (origin !== um) {
|
||||||
if (e.client_id === origin) return;
|
if (e.client_id === origin) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ws = conns.get(e.client_id)?.ws;
|
const ws = conns.get(e.client_id)?.ws;
|
||||||
|
|
||||||
if (ws) {
|
if (ws) {
|
||||||
sendWS(ws, {
|
sendWS(ws, {
|
||||||
type: SyncType.Event,
|
type: SyncType.Event,
|
||||||
event: "remote_svlocal",
|
event: "remote_svlocal",
|
||||||
data: { type: "comp", sv_local, id },
|
data: { type: "comp", sv_local, id: comp_id },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -51,16 +55,16 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!snap && !ydoc) {
|
if (!snap && !ydoc) {
|
||||||
const comp = await db.component.findFirst({ where: { id } });
|
const comp = await db.component.findFirst({ where: { id: comp_id } });
|
||||||
if (comp) {
|
if (comp) {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
let root = doc.getMap("map");
|
let root = doc.getMap("map");
|
||||||
syncronize(root, { id, root: comp.content_tree });
|
syncronize(root, { id: comp_id, root: comp.content_tree });
|
||||||
|
|
||||||
const um = await createUndoManager(root);
|
const um = await createUndoManager(root);
|
||||||
docs.comp[id] = {
|
docs.comp[comp_id] = {
|
||||||
doc: doc as any,
|
doc: doc as any,
|
||||||
id,
|
id: comp_id,
|
||||||
um,
|
um,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -69,7 +73,7 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
|
|
||||||
snapshot.update({
|
snapshot.update({
|
||||||
bin,
|
bin,
|
||||||
id,
|
id: comp_id,
|
||||||
type: "comp",
|
type: "comp",
|
||||||
name: comp.name,
|
name: comp.name,
|
||||||
ts: Date.now(),
|
ts: Date.now(),
|
||||||
|
|
@ -86,23 +90,23 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: comp_id,
|
||||||
name: comp.name,
|
name: comp.name,
|
||||||
snapshot: await gzipAsync(bin),
|
snapshot: await gzipAsync(bin),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if (snap && !ydoc) {
|
} else if (snap && !ydoc) {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
snapshot.set("comp", id, "id_doc", doc.clientID);
|
snapshot.set("comp", comp_id, "id_doc", doc.clientID);
|
||||||
Y.applyUpdate(doc, snap.bin);
|
Y.applyUpdate(doc, snap.bin);
|
||||||
let root = doc.getMap("map");
|
let root = doc.getMap("map");
|
||||||
|
|
||||||
const um = await createUndoManager(root);
|
const um = await createUndoManager(root);
|
||||||
await attachOnUpdate(doc, um);
|
await attachOnUpdate(doc, um);
|
||||||
|
|
||||||
docs.comp[id] = {
|
docs.comp[comp_id] = {
|
||||||
doc: doc as any,
|
doc: doc as any,
|
||||||
id,
|
id: comp_id,
|
||||||
um,
|
um,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -112,11 +116,11 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
user_id: sync.user_id,
|
user_id: sync.user_id,
|
||||||
site_id: conf.site_id,
|
site_id: conf.site_id,
|
||||||
page_id: conf.page_id,
|
page_id: conf.page_id,
|
||||||
comp_id: id,
|
comp_id: comp_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: comp_id,
|
||||||
name: snap.name,
|
name: snap.name,
|
||||||
snapshot: await gzipAsync(snap.bin),
|
snapshot: await gzipAsync(snap.bin),
|
||||||
};
|
};
|
||||||
|
|
@ -127,7 +131,7 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
user_id: sync.user_id,
|
user_id: sync.user_id,
|
||||||
site_id: conf.site_id,
|
site_id: conf.site_id,
|
||||||
page_id: conf.page_id,
|
page_id: conf.page_id,
|
||||||
comp_id: id,
|
comp_id: comp_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -137,3 +141,15 @@ export const loadComponent = async (id: string, sync: SyncConnection) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const userSyncComponent = (sync: SyncConnection, comp_id: string) => {
|
||||||
|
const conf = sync.conf;
|
||||||
|
|
||||||
|
user.active.add({
|
||||||
|
client_id: sync.client_id,
|
||||||
|
user_id: sync.user_id,
|
||||||
|
site_id: conf?.site_id || "",
|
||||||
|
page_id: conf?.page_id || "",
|
||||||
|
comp_id: comp_id,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ export const user = {
|
||||||
page_id: string;
|
page_id: string;
|
||||||
comp_id?: string;
|
comp_id?: string;
|
||||||
client_id: string;
|
client_id: string;
|
||||||
select: "" | "comp" | "item" | "section" | "text";
|
|
||||||
},
|
},
|
||||||
"client_id"
|
"client_id"
|
||||||
>("client_id"),
|
>("client_id"),
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
close(ws) {
|
close(ws) {
|
||||||
const client_id = wconns.get(ws);
|
const client_id = wconns.get(ws);
|
||||||
if (client_id) {
|
if (client_id) {
|
||||||
|
user.active.delAll({ client_id });
|
||||||
activity.site.disconnect(ws);
|
activity.site.disconnect(ws);
|
||||||
conns.delete(client_id);
|
conns.delete(client_id);
|
||||||
wconns.delete(ws);
|
wconns.delete(ws);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
import { NodeModel } from "@minoru/react-dnd-treeview";
|
||||||
import { compress, decompress } from "wasm-gzip";
|
import { compress, decompress } from "wasm-gzip";
|
||||||
import { IItem } from "../../../../utils/types/item";
|
import { IItem } from "../../../../utils/types/item";
|
||||||
import { DComp } from "../../../../utils/types/root";
|
import { DComp } from "../../../../utils/types/root";
|
||||||
import { genMeta } from "../../../vi/meta/meta";
|
import { genMeta } from "../../../vi/meta/meta";
|
||||||
import { IMeta, PG } from "../ed-global";
|
import { IMeta, PG } from "../ed-global";
|
||||||
import { NodeModel } from "@minoru/react-dnd-treeview";
|
|
||||||
import { pushTreeNode } from "../tree/build/push-tree";
|
import { pushTreeNode } from "../tree/build/push-tree";
|
||||||
|
|
||||||
export const loadcomp = {
|
export const loadcomp = {
|
||||||
|
|
@ -39,87 +39,108 @@ export const loadComponent = async (p: PG, id_comp: string) => {
|
||||||
|
|
||||||
export const loadCompSnapshot = async (
|
export const loadCompSnapshot = async (
|
||||||
p: PG,
|
p: PG,
|
||||||
id_comp: string,
|
comp_id: string,
|
||||||
snapshot: Uint8Array
|
snapshot: Uint8Array
|
||||||
) => {
|
) => {
|
||||||
const doc = new Y.Doc() as DComp;
|
const doc = new Y.Doc() as DComp;
|
||||||
Y.applyUpdate(doc as any, decompress(snapshot));
|
Y.applyUpdate(doc as any, decompress(snapshot));
|
||||||
const mitem = doc.getMap("map").get("root");
|
const mitem = doc.getMap("map").get("root");
|
||||||
if (mitem) {
|
if (mitem) {
|
||||||
if (typeof p.comp.list[id_comp]?.on_update === "function") {
|
if (typeof p.comp.list[comp_id]?.on_update === "function") {
|
||||||
doc.off("update", p.comp.list[id_comp].on_update);
|
doc.off("update", p.comp.list[comp_id].on_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta: Record<string, IMeta> = {};
|
const updated = updateComponentMeta(p, doc, comp_id);
|
||||||
const tree: NodeModel<IMeta>[] = [];
|
if (updated) {
|
||||||
const item = mitem.toJSON() as IItem;
|
const { meta, tree } = updated;
|
||||||
p.comp.loaded[id_comp] = {
|
if (p.comp.list[comp_id]) {
|
||||||
comp: item,
|
p.comp.list[comp_id].meta = meta;
|
||||||
};
|
p.comp.list[comp_id].tree = tree;
|
||||||
genMeta(
|
} else {
|
||||||
{
|
p.comp.list[comp_id] = {
|
||||||
comps: p.comp.loaded,
|
comp: { id: comp_id, snapshot },
|
||||||
meta,
|
doc,
|
||||||
on: {
|
meta,
|
||||||
visit(m) {
|
tree,
|
||||||
pushTreeNode(p, m, meta, tree);
|
async on_update(bin, origin) {
|
||||||
|
if (origin === "sv_remote" || origin === "local") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m.parent) {
|
const res = await p.sync.yjs.sv_local(
|
||||||
if (m.parent.id === "root") {
|
"comp",
|
||||||
if (m.item.id === item.id) {
|
comp_id,
|
||||||
m.mitem = mitem;
|
Buffer.from(compress(bin))
|
||||||
}
|
);
|
||||||
} else {
|
|
||||||
const parent = meta[m.parent.id];
|
|
||||||
|
|
||||||
if (parent.mitem) {
|
if (res) {
|
||||||
parent.mitem.get("childs")?.forEach((child) => {
|
const diff_local = Y.encodeStateAsUpdate(
|
||||||
if (child.get("id") === m.item.id) {
|
doc as any,
|
||||||
m.mitem = child;
|
decompress(res.sv)
|
||||||
}
|
);
|
||||||
});
|
Y.applyUpdate(doc as any, decompress(res.diff), "local");
|
||||||
}
|
await p.sync.yjs.diff_local(
|
||||||
|
"comp",
|
||||||
|
comp_id,
|
||||||
|
Buffer.from(compress(diff_local))
|
||||||
|
);
|
||||||
|
const updated = updateComponentMeta(p, doc, comp_id);
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
p.comp.list[comp_id].meta = updated.meta;
|
||||||
|
p.comp.list[comp_id].tree = updated.tree;
|
||||||
}
|
}
|
||||||
|
p.render();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
note: "load-comp",
|
|
||||||
},
|
|
||||||
{ item, ignore_first_component: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
p.comp.list[id_comp] = {
|
doc.on("update", p.comp.list[comp_id].on_update);
|
||||||
comp: { id: id_comp, snapshot },
|
}
|
||||||
doc,
|
}
|
||||||
meta,
|
|
||||||
tree,
|
|
||||||
async on_update(bin, origin) {
|
|
||||||
if (origin === "sv_remote" || origin === "local") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await p.sync.yjs.sv_local(
|
|
||||||
"comp",
|
|
||||||
id_comp,
|
|
||||||
Buffer.from(compress(bin))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res) {
|
|
||||||
const diff_local = Y.encodeStateAsUpdate(
|
|
||||||
doc as any,
|
|
||||||
decompress(res.sv)
|
|
||||||
);
|
|
||||||
Y.applyUpdate(doc as any, decompress(res.diff), "local");
|
|
||||||
await p.sync.yjs.diff_local(
|
|
||||||
"comp",
|
|
||||||
id_comp,
|
|
||||||
Buffer.from(compress(diff_local))
|
|
||||||
);
|
|
||||||
p.render();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
doc.on("update", p.comp.list[id_comp].on_update);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateComponentMeta = (p: PG, doc: DComp, comp_id: string) => {
|
||||||
|
const mitem = doc.getMap("map").get("root");
|
||||||
|
if (!mitem) return;
|
||||||
|
|
||||||
|
const meta: Record<string, IMeta> = {};
|
||||||
|
const tree: NodeModel<IMeta>[] = [];
|
||||||
|
const item = mitem.toJSON() as IItem;
|
||||||
|
p.comp.loaded[comp_id] = {
|
||||||
|
comp: item,
|
||||||
|
};
|
||||||
|
genMeta(
|
||||||
|
{
|
||||||
|
comps: p.comp.loaded,
|
||||||
|
meta,
|
||||||
|
on: {
|
||||||
|
visit(m) {
|
||||||
|
pushTreeNode(p, m, meta, tree);
|
||||||
|
|
||||||
|
if (m.parent) {
|
||||||
|
if (m.parent.id === "root") {
|
||||||
|
if (m.item.id === item.id) {
|
||||||
|
m.mitem = mitem;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const parent = meta[m.parent.id];
|
||||||
|
|
||||||
|
if (parent.mitem) {
|
||||||
|
parent.mitem.get("childs")?.forEach((child) => {
|
||||||
|
if (child.get("id") === m.item.id) {
|
||||||
|
m.mitem = child;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
note: "load-comp",
|
||||||
|
},
|
||||||
|
{ item, ignore_first_component: true }
|
||||||
|
);
|
||||||
|
return { meta, tree };
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { EmptySite, PG } from "./ed-global";
|
||||||
import { treeRebuild } from "./tree/build";
|
import { treeRebuild } from "./tree/build";
|
||||||
import { reloadPage } from "./ed-route";
|
import { reloadPage } from "./ed-route";
|
||||||
import { loadSite } from "./ed-site";
|
import { loadSite } from "./ed-site";
|
||||||
|
import { updateComponentMeta } from "./comp/load";
|
||||||
|
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
|
|
||||||
|
|
@ -172,9 +173,20 @@ export const edInitSync = (p: PG) => {
|
||||||
sv,
|
sv,
|
||||||
diff
|
diff
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
Y.applyUpdate(doc, decompress(res.diff), "sv_remote");
|
Y.applyUpdate(doc, decompress(res.diff), "sv_remote");
|
||||||
await treeRebuild(p, { note: "sv_remote" });
|
if (data.type === "page") {
|
||||||
|
await treeRebuild(p, { note: "sv_remote" });
|
||||||
|
} else {
|
||||||
|
const updated = updateComponentMeta(p, doc, data.id);
|
||||||
|
if (updated) {
|
||||||
|
p.comp.list[data.id].meta = updated.meta;
|
||||||
|
p.comp.list[data.id].tree = updated.tree;
|
||||||
|
}
|
||||||
|
await treeRebuild(p, { note: "sv_remote" });
|
||||||
|
}
|
||||||
|
p.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { MItem } from "../../../../../utils/types/item";
|
||||||
|
import { FNAdv } from "../../../../../utils/types/meta-fn";
|
||||||
|
import { PG } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const edMonacoDefaultVal = (p: PG, adv: FNAdv, mitem: MItem) => {
|
||||||
|
let val = "";
|
||||||
|
|
||||||
|
if (p.ui.popup.script.type === "item") {
|
||||||
|
const mode = p.ui.popup.script.mode;
|
||||||
|
val = (typeof adv[mode] === "string" ? adv[mode] : "") as any;
|
||||||
|
|
||||||
|
if (val === "") {
|
||||||
|
if (mode === "js") {
|
||||||
|
val = `<div {...props}>{children}</div>`;
|
||||||
|
} else if (mode === "css") {
|
||||||
|
val = `\
|
||||||
|
& {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// &.mobile {}
|
||||||
|
// &.desktop {}
|
||||||
|
// &:hover {}
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
p.ui.popup.script.type === "prop-master" ||
|
||||||
|
p.ui.popup.script.type === "prop-instance"
|
||||||
|
) {
|
||||||
|
const mprops = mitem?.get("component")?.get("props");
|
||||||
|
if (mprops) {
|
||||||
|
const mprop = mprops.get(p.ui.popup.script.prop_name);
|
||||||
|
if (mprop) {
|
||||||
|
const kind = p.ui.popup.script.prop_kind;
|
||||||
|
if (kind === "value") {
|
||||||
|
val = mprop.get("value");
|
||||||
|
} else if (kind === "gen") {
|
||||||
|
val =
|
||||||
|
mprop.get("gen") ||
|
||||||
|
`\
|
||||||
|
async () => {
|
||||||
|
return \`""\`;
|
||||||
|
}`;
|
||||||
|
} else if (kind === "visible") {
|
||||||
|
val = mprop.get("visible") || "true";
|
||||||
|
} else if (kind === "option") {
|
||||||
|
val =
|
||||||
|
mprop.get("meta")?.get("options") ||
|
||||||
|
`\
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: "yes",
|
||||||
|
value: "y"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "no",
|
||||||
|
value: "n"
|
||||||
|
},
|
||||||
|
]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import type { Monaco, OnMount } from "@monaco-editor/react";
|
import type { Monaco, OnMount } from "@monaco-editor/react";
|
||||||
import { createStore } from "idb-keyval";
|
import { createStore } from "idb-keyval";
|
||||||
import trim from "lodash.trim";
|
import trim from "lodash.trim";
|
||||||
import { useEffect } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { compress } from "wasm-gzip";
|
import { compress } from "wasm-gzip";
|
||||||
import { useGlobal, useLocal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { jscript } from "../../../../../utils/script/jscript";
|
import { jscript } from "../../../../../utils/script/jscript";
|
||||||
|
|
@ -10,6 +10,7 @@ import { monacoTypings } from "../../../../../utils/script/typings";
|
||||||
import { EDGlobal, IMeta, active } from "../../../logic/ed-global";
|
import { EDGlobal, IMeta, active } from "../../../logic/ed-global";
|
||||||
import { getMetaById } from "../../../logic/tree/build";
|
import { getMetaById } from "../../../logic/tree/build";
|
||||||
import { declareScope } from "./scope";
|
import { declareScope } from "./scope";
|
||||||
|
import { edMonacoDefaultVal } from "./default-val";
|
||||||
|
|
||||||
const scriptEdit = {
|
const scriptEdit = {
|
||||||
timeout: null as any,
|
timeout: null as any,
|
||||||
|
|
@ -17,7 +18,7 @@ const scriptEdit = {
|
||||||
|
|
||||||
const encode = new TextEncoder();
|
const encode = new TextEncoder();
|
||||||
export type MonacoEditor = Parameters<OnMount>[0];
|
export type MonacoEditor = Parameters<OnMount>[0];
|
||||||
export const ScriptMonaco = () => {
|
export const EdScriptMonaco: FC<{}> = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
editor: null as null | MonacoEditor,
|
editor: null as null | MonacoEditor,
|
||||||
|
|
@ -26,6 +27,7 @@ export const ScriptMonaco = () => {
|
||||||
init: false,
|
init: false,
|
||||||
value: "",
|
value: "",
|
||||||
historyOpen: false,
|
historyOpen: false,
|
||||||
|
mode: "",
|
||||||
idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"),
|
idbstore: createStore(`prasi-page-${p.page.cur.id}`, "script-history"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -53,6 +55,11 @@ export const ScriptMonaco = () => {
|
||||||
const monaco = local.monaco;
|
const monaco = local.monaco;
|
||||||
|
|
||||||
if (monaco && editor) {
|
if (monaco && editor) {
|
||||||
|
if (local.mode !== p.ui.popup.script.mode) {
|
||||||
|
local.init = false;
|
||||||
|
local.mode = p.ui.popup.script.mode;
|
||||||
|
}
|
||||||
|
|
||||||
if (!local.init) {
|
if (!local.init) {
|
||||||
if (p.ui.popup.script.mode === "js") {
|
if (p.ui.popup.script.mode === "js") {
|
||||||
monaco.editor.getModels().forEach((model) => {
|
monaco.editor.getModels().forEach((model) => {
|
||||||
|
|
@ -101,7 +108,7 @@ export const ScriptMonaco = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, [active.item_id, local.monaco, local.editor]);
|
}, [active.item_id, local.monaco, local.editor, p.ui.popup.script.mode]);
|
||||||
|
|
||||||
if (!meta) return null;
|
if (!meta) return null;
|
||||||
|
|
||||||
|
|
@ -110,41 +117,45 @@ export const ScriptMonaco = () => {
|
||||||
item.adv = adv;
|
item.adv = adv;
|
||||||
|
|
||||||
const doEdit = async (newval: string, all?: boolean) => {
|
const doEdit = async (newval: string, all?: boolean) => {
|
||||||
if (local.editor && jscript.prettier.standalone) {
|
if (local.editor) {
|
||||||
const text = trim(
|
const prettier = jscript.prettier.standalone;
|
||||||
await jscript.prettier.standalone.format(
|
const prettier_ts = jscript.prettier.ts;
|
||||||
all
|
const prettier_estree = jscript.prettier.estree;
|
||||||
? newval
|
|
||||||
: local.editor?.getValue().replace(/\{\s*children\s*\}/gi, newval)
|
|
||||||
),
|
|
||||||
"; \n"
|
|
||||||
);
|
|
||||||
|
|
||||||
local.editor.executeEdits(null, [
|
if (prettier && prettier_estree && prettier_ts) {
|
||||||
{
|
const text = trim(
|
||||||
range: {
|
await prettier.format(
|
||||||
startLineNumber: 0,
|
all
|
||||||
startColumn: 0,
|
? newval
|
||||||
endColumn: Number.MAX_SAFE_INTEGER,
|
: local.editor
|
||||||
endLineNumber: Number.MAX_SAFE_INTEGER,
|
?.getValue()
|
||||||
|
.replace(/\{\s*children\s*\}/gi, newval),
|
||||||
|
{
|
||||||
|
parser: "typescript",
|
||||||
|
plugins: [prettier_ts, prettier_estree],
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"; \n"
|
||||||
|
);
|
||||||
|
|
||||||
|
local.editor.executeEdits(null, [
|
||||||
|
{
|
||||||
|
range: {
|
||||||
|
startLineNumber: 0,
|
||||||
|
startColumn: 0,
|
||||||
|
endColumn: Number.MAX_SAFE_INTEGER,
|
||||||
|
endLineNumber: Number.MAX_SAFE_INTEGER,
|
||||||
|
},
|
||||||
|
text,
|
||||||
},
|
},
|
||||||
text,
|
]);
|
||||||
},
|
}
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
p.script.do_edit = doEdit;
|
p.script.do_edit = doEdit;
|
||||||
|
|
||||||
let mitem = meta.mitem;
|
let mitem = meta.mitem;
|
||||||
|
|
||||||
if (p.ui.popup.script.type === "item") {
|
|
||||||
val = (
|
|
||||||
typeof adv[p.ui.popup.script.mode] === "string"
|
|
||||||
? adv[p.ui.popup.script.mode]
|
|
||||||
: ""
|
|
||||||
) as any;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mitem) {
|
if (!mitem) {
|
||||||
active.item_id = "";
|
active.item_id = "";
|
||||||
return <div>no mitem</div>;
|
return <div>no mitem</div>;
|
||||||
|
|
@ -155,44 +166,7 @@ export const ScriptMonaco = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
val = edMonacoDefaultVal(p, adv, mitem);
|
||||||
p.ui.popup.script.type === "prop-master" ||
|
|
||||||
p.ui.popup.script.type === "prop-instance"
|
|
||||||
) {
|
|
||||||
const mprops = mitem?.get("component")?.get("props");
|
|
||||||
if (mprops) {
|
|
||||||
const mprop = mprops.get(p.ui.popup.script.prop_name);
|
|
||||||
if (mprop) {
|
|
||||||
const kind = p.ui.popup.script.prop_kind;
|
|
||||||
if (kind === "value") {
|
|
||||||
val = mprop.get("value");
|
|
||||||
} else if (kind === "gen") {
|
|
||||||
val =
|
|
||||||
mprop.get("gen") ||
|
|
||||||
`\
|
|
||||||
async () => {
|
|
||||||
return \`""\`;
|
|
||||||
}`;
|
|
||||||
} else if (kind === "visible") {
|
|
||||||
val = mprop.get("visible") || "true";
|
|
||||||
} else if (kind === "option") {
|
|
||||||
val =
|
|
||||||
mprop.get("meta")?.get("options") ||
|
|
||||||
`\
|
|
||||||
[
|
|
||||||
{
|
|
||||||
label: "yes",
|
|
||||||
value: "y"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "no",
|
|
||||||
value: "n"
|
|
||||||
},
|
|
||||||
]`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Editor
|
<Editor
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import { Loading } from "../../../../../utils/ui/loading";
|
||||||
import { Modal } from "../../../../../utils/ui/modal";
|
import { Modal } from "../../../../../utils/ui/modal";
|
||||||
import { EDGlobal } from "../../../logic/ed-global";
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
import { propPopover } from "../../side/prop-master/prop-form";
|
import { propPopover } from "../../side/prop-master/prop-form";
|
||||||
import { ScriptWorkbench } from "./workbench";
|
import { EdScriptWorkbench } from "./workbench";
|
||||||
|
|
||||||
export const EdPopScript = () => {
|
export const EdPopScript = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
@ -80,7 +80,7 @@ export const EdPopScript = () => {
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{!jscript.editor && <Loading note={"js-editor"} backdrop={false} />}
|
{!jscript.editor && <Loading note={"js-editor"} backdrop={false} />}
|
||||||
{jscript.editor && <ScriptWorkbench />}
|
{jscript.editor && <EdScriptWorkbench />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import { Button } from "../../../../../utils/ui/form/Button";
|
||||||
|
import { useGlobal } from "web-utils";
|
||||||
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const EdScriptSnippet: FC<{}> = ({}) => {
|
||||||
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center space-x-1 pl-2 border-l">
|
||||||
|
<Button
|
||||||
|
className={cx(css`
|
||||||
|
width: auto !important;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
`)}
|
||||||
|
onClick={() => {
|
||||||
|
console.log(p.script.do_edit);
|
||||||
|
p.script.do_edit(
|
||||||
|
`\
|
||||||
|
<div {...props}>
|
||||||
|
<Local
|
||||||
|
name="local"
|
||||||
|
value={
|
||||||
|
{
|
||||||
|
//local object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
effect={async (local) => {
|
||||||
|
//local effect
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Local>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Local/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,53 +1,57 @@
|
||||||
import { useGlobal } from "web-utils";
|
import { useGlobal } from "web-utils";
|
||||||
import { ScriptMonaco } from "./monaco";
|
import { EdScriptMonaco } from "./monaco";
|
||||||
import { EDGlobal, active } from "../../../logic/ed-global";
|
import { EDGlobal, active } from "../../../logic/ed-global";
|
||||||
import { IItem } from "../../../../../utils/types/item";
|
import { IItem } from "../../../../../utils/types/item";
|
||||||
|
import { EdScriptSnippet } from "./snippet";
|
||||||
|
|
||||||
export const ScriptWorkbench = () => {
|
export const EdScriptWorkbench = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 items-stretch">
|
<div className="flex flex-1 items-stretch">
|
||||||
<div className="flex flex-1 flex-col ">
|
<div className="flex flex-1 flex-col ">
|
||||||
<div className="flex p-2 border-b space-x-2">
|
<div className="flex border-b">
|
||||||
{p.ui.popup.script.type === "prop-master" ? (
|
{p.ui.popup.script.type === "prop-master" ? (
|
||||||
<CompTitle />
|
<CompTitle />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{[
|
<div className="flex p-2 space-x-1">
|
||||||
{ type: "js", color: "#e9522c" },
|
{[
|
||||||
{ type: "css", color: "#188228" },
|
{ type: "js", color: "#e9522c" },
|
||||||
{ type: "html", color: "#2c3e83" },
|
{ type: "css", color: "#188228" },
|
||||||
].map((e) => {
|
{ type: "html", color: "#2c3e83" },
|
||||||
return (
|
].map((e) => {
|
||||||
<div
|
return (
|
||||||
key={e.type}
|
<div
|
||||||
className={cx(
|
key={e.type}
|
||||||
css`
|
className={cx(
|
||||||
color: ${e.color};
|
css`
|
||||||
border: 1px solid ${e.color};
|
color: ${e.color};
|
||||||
`,
|
border: 1px solid ${e.color};
|
||||||
"uppercase text-white text-[12px] cursor-pointer transition-all hover:opacity-100 w-[40px] text-center",
|
`,
|
||||||
p.ui.popup.script.mode === e.type
|
"uppercase text-white text-[12px] cursor-pointer flex items-center justify-center transition-all hover:opacity-100 w-[40px] text-center",
|
||||||
? css`
|
p.ui.popup.script.mode === e.type
|
||||||
background: ${e.color};
|
? css`
|
||||||
color: white;
|
background: ${e.color};
|
||||||
`
|
color: white;
|
||||||
: "opacity-30"
|
`
|
||||||
)}
|
: "opacity-30"
|
||||||
onClick={() => {
|
)}
|
||||||
p.ui.popup.script.mode = e.type as any;
|
onClick={() => {
|
||||||
p.render();
|
p.ui.popup.script.mode = e.type as any;
|
||||||
}}
|
p.render();
|
||||||
>
|
}}
|
||||||
{e.type}
|
>
|
||||||
</div>
|
{e.type}
|
||||||
);
|
</div>
|
||||||
})}
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
{p.ui.popup.script.mode === "js" && <EdScriptSnippet />}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex flex-1">
|
<div className="relative flex flex-1">
|
||||||
<ScriptMonaco />
|
<EdScriptMonaco />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,15 @@ export const EdSidePropComp: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
const TypedTree = DNDTree<PropItem>;
|
const TypedTree = DNDTree<PropItem>;
|
||||||
|
|
||||||
let filtered = [] as NodeModel<PropItem>[];
|
let filtered = [] as NodeModel<PropItem>[];
|
||||||
const mprops = meta.mitem?.get("component")?.get("props");
|
let mprops = meta.mitem?.get("component")?.get("props");
|
||||||
|
if (!mprops) {
|
||||||
|
const mcomp = meta.mitem?.get("component");
|
||||||
|
if (mcomp) {
|
||||||
|
mcomp.set("props", new Y.Map() as any);
|
||||||
|
mprops = mcomp.get("props");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mprops && meta.mitem) {
|
if (mprops && meta.mitem) {
|
||||||
mprops.forEach((m, key) => {
|
mprops.forEach((m, key) => {
|
||||||
filtered.push({
|
filtered.push({
|
||||||
|
|
@ -139,13 +147,13 @@ export const EdSidePropComp: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
/>
|
/>
|
||||||
</DndProvider>
|
</DndProvider>
|
||||||
<div
|
<div
|
||||||
className="m-1 border border-blue-200 px-2 self-start text-[13px] hover:bg-blue-100 cursor-pointer"
|
className="m-1 border border-blue-200 px-2 self-start text-[13px] hover:bg-blue-100 cursor-pointer select-none"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (mprops) {
|
if (mprops) {
|
||||||
const indexes: (number | undefined)[] = [];
|
const indexes: (number | undefined)[] = [];
|
||||||
mprops.forEach((e) => indexes.push(e.get("idx")));
|
mprops.forEach((e) => indexes.push(e.get("idx")));
|
||||||
let idx: any = (indexes.sort().pop() || 0) + 1;
|
let idx: any = (indexes.sort().pop() || 0) + 1;
|
||||||
const name = `prop_${idx + 1}`;
|
const name = `prop_${indexes.length === 0 ? 1 : idx + 1}`;
|
||||||
const map = new Y.Map() as FMCompDef;
|
const map = new Y.Map() as FMCompDef;
|
||||||
syncronize(map, {
|
syncronize(map, {
|
||||||
idx: idx,
|
idx: idx,
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,11 @@ export const propPopover = {
|
||||||
name: "",
|
name: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({
|
export const EdPropPopoverForm: FC<{
|
||||||
mprop,
|
mprop: FMCompDef;
|
||||||
name,
|
name: string;
|
||||||
}) => {
|
closing: boolean;
|
||||||
|
}> = ({ mprop, name, closing }) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
const mmeta = mprop.get("meta");
|
const mmeta = mprop.get("meta");
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
|
|
@ -28,7 +29,8 @@ export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"flex text-sm flex-col items-stretch space-y-1 py-1 w-[300px]"
|
"flex text-sm flex-col items-stretch space-y-1 py-1 w-[300px]",
|
||||||
|
closing && "hidden"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="px-2 py-1 flex space-x-1">
|
<div className="px-2 py-1 flex space-x-1">
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
import { Popover } from "../../../../../utils/ui/popover";
|
import { Popover } from "../../../../../utils/ui/popover";
|
||||||
import { EdPropPopoverForm, propPopover } from "./prop-form";
|
import { EdPropPopoverForm, propPopover } from "./prop-form";
|
||||||
import { TypedMap } from "yjs-types";
|
import { TypedMap } from "yjs-types";
|
||||||
|
import { useLocal } from "web-utils";
|
||||||
|
|
||||||
export type PropItem = {
|
export type PropItem = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -18,6 +19,7 @@ export const EdPropCompTreeItem: FC<{
|
||||||
params: Parameters<NodeRender<PropItem>>[1];
|
params: Parameters<NodeRender<PropItem>>[1];
|
||||||
render: () => void;
|
render: () => void;
|
||||||
}> = ({ node, params, render }) => {
|
}> = ({ node, params, render }) => {
|
||||||
|
const local = useLocal({ closing: false });
|
||||||
if (node.id === "root") {
|
if (node.id === "root") {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
@ -51,14 +53,24 @@ export const EdPropCompTreeItem: FC<{
|
||||||
popoverClassName="bg-white shadow-lg border border-slate-300"
|
popoverClassName="bg-white shadow-lg border border-slate-300"
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
propPopover.name = "";
|
local.closing = true;
|
||||||
|
local.render();
|
||||||
|
setTimeout(() => {
|
||||||
|
propPopover.name = "";
|
||||||
|
render();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
local.closing = false;
|
||||||
propPopover.name = node.text;
|
propPopover.name = node.text;
|
||||||
|
render();
|
||||||
}
|
}
|
||||||
render();
|
|
||||||
}}
|
}}
|
||||||
content={
|
content={
|
||||||
<EdPropPopoverForm mprop={node.data.mprop} name={node.text} />
|
<EdPropPopoverForm
|
||||||
|
closing={local.closing}
|
||||||
|
mprop={node.data.mprop}
|
||||||
|
name={node.text}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
className="flex-1 pl-1 hover:bg-blue-100 cursor-pointer items-center flex"
|
className="flex-1 pl-1 hover:bg-blue-100 cursor-pointer items-center flex"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,24 @@ type CompilerOptions = Parameters<
|
||||||
|
|
||||||
export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
|
export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
|
||||||
const m = monaco as any;
|
const m = monaco as any;
|
||||||
|
|
||||||
|
if (editor.getModel()) {
|
||||||
|
const jsxHgController = new MonacoJsxSyntaxHighlight(getWorker(), monaco);
|
||||||
|
const { highlighter } = jsxHgController.highlighterBuilder({
|
||||||
|
editor: editor,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof editor.getModel === "function") {
|
||||||
|
highlighter();
|
||||||
|
}
|
||||||
|
editor.onDidChangeModelContent(() => {
|
||||||
|
if (typeof editor.getModel === "function") {
|
||||||
|
try {
|
||||||
|
highlighter();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
if (!m.customJSMounted) {
|
if (!m.customJSMounted) {
|
||||||
m.customJSMounted = true;
|
m.customJSMounted = true;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -267,24 +285,6 @@ export const jsMount = async (editor: MonacoEditor, monaco: Monaco, p?: PG) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (editor.getModel()) {
|
|
||||||
const jsxHgController = new MonacoJsxSyntaxHighlight(getWorker(), monaco);
|
|
||||||
const { highlighter } = jsxHgController.highlighterBuilder({
|
|
||||||
editor: editor,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof editor.getModel === "function") {
|
|
||||||
highlighter();
|
|
||||||
}
|
|
||||||
editor.onDidChangeModelContent(() => {
|
|
||||||
if (typeof editor.getModel === "function") {
|
|
||||||
try {
|
|
||||||
highlighter();
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.getAction("editor.action.formatDocument")?.run();
|
editor.getAction("editor.action.formatDocument")?.run();
|
||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue