@jxsuite/studio 10.5.0 → 10.6.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/data/locales/en/elements.json +434 -0
- package/data/webdata.json +116 -139
- package/dist/chunks/{2020-7sx2vexa.js → 2020-rqm7qrje.js} +3 -3
- package/dist/chunks/adapter-cyy8vbcx.js +4 -0
- package/dist/chunks/add-new-flow-8cgtejv2.js +4 -0
- package/dist/chunks/{cf-account-picker-ajh60k54.js → cf-account-picker-v3qd2dhw.js} +3 -3
- package/dist/chunks/cf-settings-1fnw874z.js +4 -0
- package/dist/chunks/{color-area-gbcftzh3.js → color-area-frd9y9q6.js} +2 -2
- package/dist/chunks/{color-field-85136598.js → color-field-rebpbe33.js} +3 -3
- package/dist/chunks/{color-slider-w1s3ndd8.js → color-slider-6bzmk3s7.js} +2 -2
- package/dist/chunks/color-t2bnnj8y.js +4 -0
- package/dist/chunks/{combobox-dk98wc5x.js → combobox-c49x7gf1.js} +2 -2
- package/dist/chunks/components-y8yhdd7d.js +4 -0
- package/dist/chunks/content-source-9e7qvmsf.js +4 -0
- package/dist/chunks/convert-to-repeater-pd2w4z21.js +4 -0
- package/dist/chunks/editor-mb9jzdrw.js +4 -0
- package/dist/chunks/entry-commands-at0wnx3f.js +4 -0
- package/dist/chunks/extension-sections-4z9qq0gh.js +4 -0
- package/dist/chunks/file-ops-dtdvjmza.js +4 -0
- package/dist/chunks/files-8pf70854.js +4 -0
- package/dist/chunks/format-host-fd3m2y2a.js +4 -0
- package/dist/chunks/fs-events-hrk29vcv.js +4 -0
- package/dist/chunks/grid-open-bh74v82z.js +4 -0
- package/dist/chunks/{grid-view-0v4hjspb.js → grid-view-a51mgzmq.js} +10 -10
- package/dist/chunks/{icons-j9eksgew.js → icons-qp8fn1k8.js} +2 -2
- package/dist/chunks/{iframe-entry-4zqtn3ry.js → iframe-entry-mpwe5pwk.js} +4 -4
- package/dist/chunks/{iframe-entry-2x9bn5ng.js → iframe-entry-msd43x9h.js} +4 -4
- package/dist/chunks/iframe-entry-rt8jz5t8.js +5 -0
- package/dist/chunks/{iframe-entry-54kwwhmg.js → iframe-entry-v40cr813.js} +2 -2
- package/dist/chunks/iframe-host-q0s0wwy3.js +4 -0
- package/dist/chunks/{image-bake-m8gzaan9.js → image-bake-q9ajdjsj.js} +3 -3
- package/dist/chunks/{image-editor-0afyws7c.js → image-editor-ke9std9b.js} +2 -2
- package/dist/chunks/index-57ang7ma.js +4 -0
- package/dist/chunks/index-eytr7av4.js +17 -0
- package/dist/chunks/{index-2q88g57p.js → index-x495reff.js} +3 -3
- package/dist/chunks/{javascript-5sxtr1g7.js → javascript-qe34bvaz.js} +3 -3
- package/dist/chunks/{jsonMode-m6sf47hq.js → jsonMode-m8rseh31.js} +8 -8
- package/dist/chunks/jx-validate-bbd1mary.js +4 -0
- package/dist/chunks/layers-panel-wcjtdqsa.js +4 -0
- package/dist/chunks/layers-yscpys6q.js +4 -0
- package/dist/chunks/{listbox-k5p41049.js → listbox-tktzq5xj.js} +2 -2
- package/dist/chunks/lit-html-qm5wbhqz.js +4 -0
- package/dist/chunks/media-library-2hfff88g.js +4 -0
- package/dist/chunks/media-open-4pb05cne.js +4 -0
- package/dist/chunks/media-picker-bzktmmwr.js +4 -0
- package/dist/chunks/{menu-26nez152.js → menu-xc3cbgsd.js} +2 -2
- package/dist/chunks/{monaco-binding-1s2b8snq.js → monaco-binding-7t38arh9.js} +3 -3
- package/dist/chunks/monaco-buffer-3vz94c9f.js +4 -0
- package/dist/chunks/monaco-setup-fstdew02.js +4 -0
- package/dist/chunks/notify-gbdcckrh.js +4 -0
- package/dist/chunks/parse-fpdzgk4c.js +4 -0
- package/dist/chunks/platform-9g72gdqr.js +4 -0
- package/dist/chunks/{popover-fhdnt4be.js → popover-cnmsav6b.js} +2 -2
- package/dist/chunks/publish-panel-91x1cb5d.js +4 -0
- package/dist/chunks/publish-quick-e2dmf7eg.js +4 -0
- package/dist/chunks/publish-workspace-1x8mnzrj.js +4 -0
- package/dist/chunks/quick-search-2m4y6p1x.js +4 -0
- package/dist/chunks/references-yg1g9rwx.js +4 -0
- package/dist/chunks/right-panel-7mfyhzrk.js +4 -0
- package/dist/chunks/source-control-rrc4jgp5.js +4 -0
- package/dist/chunks/{split-qh21j2b0.js → split-d15yencd.js} +2 -2
- package/dist/chunks/{studio-r5g7fx7q.js → studio-0jhhznxy.js} +6 -6
- package/dist/chunks/studio-0nb57pjg.js +7 -0
- package/dist/chunks/{studio-bpzwhn88.js → studio-0wa4wv4s.js} +4 -4
- package/dist/chunks/studio-0z8kp4xk.js +5 -0
- package/dist/chunks/{studio-jqvke4ac.js → studio-18gc5t3v.js} +4 -4
- package/dist/chunks/{studio-xh6rf05g.js → studio-1b79rpcb.js} +4 -4
- package/dist/chunks/studio-211q5j7m.js +4 -0
- package/dist/chunks/studio-213pyfxh.js +16 -0
- package/dist/chunks/studio-2b1smjvp.js +5 -0
- package/dist/chunks/{studio-dst8y8vh.js → studio-2v6tc9jp.js} +4 -4
- package/dist/chunks/studio-30j0wz99.js +5 -0
- package/dist/chunks/studio-3kmqhwtt.js +5 -0
- package/dist/chunks/studio-44drsmhw.js +5 -0
- package/dist/chunks/{studio-d5f7sskn.js → studio-495b6f2r.js} +4 -4
- package/dist/chunks/{studio-g65t6svn.js → studio-4gthb2fd.js} +4 -4
- package/dist/chunks/{studio-bmwgj8ez.js → studio-4xadhxj1.js} +4 -4
- package/dist/chunks/{studio-zav9hgb3.js → studio-52mzbxqm.js} +4 -4
- package/dist/chunks/{studio-thgexj3w.js → studio-56mmnsw8.js} +7 -7
- package/dist/chunks/studio-59hz8f4r.js +5 -0
- package/dist/chunks/{studio-bk0anq3b.js → studio-5k9mfafh.js} +3 -3
- package/dist/chunks/{studio-qarg1xf9.js → studio-5qez462c.js} +5 -5
- package/dist/chunks/studio-6tnpg0vx.js +5 -0
- package/dist/chunks/studio-6w8mt734.js +6 -0
- package/dist/chunks/studio-7hm04x5z.js +5 -0
- package/dist/chunks/studio-8atmfjjm.js +7 -0
- package/dist/chunks/{studio-69g6a0jn.js → studio-8n99z71s.js} +4 -4
- package/dist/chunks/{studio-ep1384t9.js → studio-8vmad6x2.js} +4 -4
- package/dist/chunks/{studio-6sxnqqw8.js → studio-93p5k4r4.js} +4 -4
- package/dist/chunks/{studio-hy936516.js → studio-9gb0m81w.js} +4 -4
- package/dist/chunks/{studio-ek4fb4eb.js → studio-a4ymg4vd.js} +4 -4
- package/dist/chunks/studio-anc8067x.js +5 -0
- package/dist/chunks/{studio-ketrgtph.js → studio-dbdt67kr.js} +5 -5
- package/dist/chunks/studio-dbex091t.js +5 -0
- package/dist/chunks/{studio-nngc45ct.js → studio-dj8ctxey.js} +4 -4
- package/dist/chunks/{studio-pgze9p34.js → studio-ed9bz68j.js} +5 -5
- package/dist/chunks/{studio-4ncxzw5m.js → studio-fe2d1fp5.js} +4 -4
- package/dist/chunks/{studio-m8hesdrw.js → studio-fgp4cyy3.js} +4 -4
- package/dist/chunks/{studio-151kgn69.js → studio-ft706q02.js} +4 -4
- package/dist/chunks/{studio-pv1ts08p.js → studio-g79s1dyg.js} +5 -5
- package/dist/chunks/{studio-zkkt13qd.js → studio-gahswxp4.js} +4 -4
- package/dist/chunks/{studio-x5ffyssw.js → studio-gbqc12bk.js} +4 -4
- package/dist/chunks/{studio-4jy967rj.js → studio-gxphbetb.js} +5 -5
- package/dist/chunks/studio-hdf01j7q.js +7 -0
- package/dist/chunks/studio-hf259xzd.js +48 -0
- package/dist/chunks/studio-jbva4wxw.js +5 -0
- package/dist/chunks/{studio-td3h1644.js → studio-jj9gf1qc.js} +4 -4
- package/dist/chunks/studio-jsjg3mjv.js +5 -0
- package/dist/chunks/studio-jtvb8hd7.js +5 -0
- package/dist/chunks/{studio-c72v1kwc.js → studio-kp4vzrct.js} +4 -4
- package/dist/chunks/{studio-s4k1v7dt.js → studio-kpx02gaa.js} +6 -6
- package/dist/chunks/{studio-3yr1zdp9.js → studio-kv1728ex.js} +8 -8
- package/dist/chunks/studio-m25ry0mf.js +5 -0
- package/dist/chunks/studio-mcbwmkyh.js +5 -0
- package/dist/chunks/studio-meajkr51.js +5 -0
- package/dist/chunks/studio-mkjrjpr2.js +6 -0
- package/dist/chunks/{studio-nv5eq0f7.js → studio-mr084886.js} +181 -181
- package/dist/chunks/{studio-43pynnhz.js → studio-mrb10hv3.js} +4 -4
- package/dist/chunks/{studio-7qqb7hb8.js → studio-nhpg405j.js} +4 -4
- package/dist/chunks/{studio-n271vdsg.js → studio-nsec0hxm.js} +41 -41
- package/dist/chunks/{studio-ztzf8mce.js → studio-nv0mh0p5.js} +4 -4
- package/dist/chunks/studio-pafmb06w.js +5 -0
- package/dist/chunks/{studio-4s5bka8t.js → studio-pgftd79b.js} +4 -4
- package/dist/chunks/{studio-wn2cmf9q.js → studio-pk961xgz.js} +4 -4
- package/dist/chunks/studio-pzbr7g05.js +5 -0
- package/dist/chunks/{studio-15mfah02.js → studio-qcc5hsw2.js} +6 -6
- package/dist/chunks/studio-qfq58c8n.js +5 -0
- package/dist/chunks/{studio-j3bq30yz.js → studio-qvb2jr83.js} +4 -4
- package/dist/chunks/studio-r85zw6ay.js +5 -0
- package/dist/chunks/{studio-f69wcajk.js → studio-s0kwce5w.js} +5 -5
- package/dist/chunks/studio-s6ymkf3q.js +14 -0
- package/dist/chunks/{studio-8ncm9zwx.js → studio-s7p5ccxa.js} +4 -4
- package/dist/chunks/{studio-zzgp5yka.js → studio-s9jjap3x.js} +4 -4
- package/dist/chunks/{studio-ber1dgte.js → studio-t5hde1ws.js} +4 -4
- package/dist/chunks/studio-vj9yv897.js +5 -0
- package/dist/chunks/{studio-ajfq4fmr.js → studio-wmak8xjw.js} +4 -4
- package/dist/chunks/{studio-k05g7efh.js → studio-wqsmvtqj.js} +4 -4
- package/dist/chunks/studio-x3z3rhej.js +5 -0
- package/dist/chunks/{studio-7qr8k0v2.js → studio-xb55kpmy.js} +4 -4
- package/dist/chunks/{studio-f3awr5nc.js → studio-xxtdajmv.js} +7 -7
- package/dist/chunks/{studio-1a7zshnv.js → studio-xxttcym1.js} +4 -4
- package/dist/chunks/{studio-czpmzs9r.js → studio-y2zsnzye.js} +7 -7
- package/dist/chunks/{studio-9f5vcb4w.js → studio-y3tjh2xb.js} +3 -3
- package/dist/chunks/studio-y4f1rdsj.js +5 -0
- package/dist/chunks/studio-ybkd5w8k.js +5 -0
- package/dist/chunks/{studio-cv6gnjqd.js → studio-yetr4gg1.js} +4 -4
- package/dist/chunks/{studio-ehj3csbm.js → studio-z295anhs.js} +5 -5
- package/dist/chunks/{studio-pte5w7rf.js → studio-z89e6wpg.js} +8 -8
- package/dist/chunks/{studio-4z0cdh16.js → studio-zbwr6prc.js} +3 -3
- package/dist/chunks/{studio-w3aafbpk.js → studio-zdbsv5q2.js} +3 -3
- package/dist/chunks/{studio-eq5vqn1q.js → studio-zvthj8hg.js} +4 -4
- package/dist/chunks/toast-2kn2vrn4.js +4 -0
- package/dist/chunks/{toast-host-g3r2s0kn.js → toast-host-3rxeyj3d.js} +3 -3
- package/dist/chunks/{tooltip-gtx40bjg.js → tooltip-ghkxkasp.js} +2 -2
- package/dist/chunks/{tree-a19s1c05.js → tree-vw4nc63s.js} +2 -2
- package/dist/chunks/{tsMode-3f116hth.js → tsMode-7gngmamr.js} +7 -7
- package/dist/chunks/workspace-gv0hxgsm.js +4 -0
- package/dist/chunks/workspace-home-j7e0mjy5.js +4 -0
- package/dist/chunks/{ws-client-cb49m87s.js → ws-client-vs11sxc5.js} +3 -3
- package/dist/iframe-entry.js +14 -14
- package/dist/manifest.json +84 -83
- package/dist/studio.js +80 -80
- package/package.json +12 -12
- package/src/browse/preview-style.ts +2 -1
- package/src/canvas/canvas-render.ts +6 -1
- package/src/canvas/iframe-drop.ts +84 -1
- package/src/canvas/iframe-entry.ts +9 -6
- package/src/canvas/iframe-render.ts +13 -0
- package/src/collab/collab-session.ts +2 -2
- package/src/commands/levels.ts +1 -1
- package/src/create/add-new-flow.ts +2 -1
- package/src/editor/convert-targets.ts +2 -23
- package/src/editor/slash-menu.ts +35 -17
- package/src/files/files.ts +18 -0
- package/src/format/format-choices.ts +5 -5
- package/src/format/format-host.ts +35 -3
- package/src/grid/redirects-grid.ts +4 -4
- package/src/locale/element-names.ts +131 -0
- package/src/panels/dnd.ts +3 -1
- package/src/panels/elements-panel.ts +93 -36
- package/src/panels/imports-panel.ts +3 -2
- package/src/panels/navigator-panels.ts +10 -10
- package/src/panels/panel-registry.ts +3 -3
- package/src/panels/site-panel.ts +2 -1
- package/src/panels/style-panel.ts +2 -1
- package/src/panels/styles-panel.ts +2 -2
- package/src/platforms/cloud.ts +5 -2
- package/src/services/ai-command-tools.ts +2 -1
- package/src/services/ai-project-tools.ts +18 -5
- package/src/services/jxn-language.ts +110 -0
- package/src/services/model-uri.ts +3 -0
- package/src/services/monaco-setup.ts +6 -2
- package/src/settings/contributed-section.ts +2 -1
- package/src/settings/extension-commands.ts +2 -1
- package/src/settings/general-settings.ts +2 -2
- package/src/settings/settings-document.ts +5 -5
- package/src/shell.ts +1 -1
- package/src/studio.ts +28 -11
- package/src/style/variables-view.ts +2 -2
- package/src/surfaces/panel-elements.json +466 -206
- package/src/surfaces/panel-elements.ts +61 -25
- package/src/tabs/project-config.ts +13 -13
- package/src/tabs/tab.ts +7 -2
- package/src/types.ts +11 -2
- package/src/view.ts +9 -2
- package/src/workspace/tab-workspace.ts +2 -2
- package/src/workspace/workspace-back.ts +2 -2
- package/dist/chunks/adapter-12dxr3z7.js +0 -4
- package/dist/chunks/add-new-flow-any4pw2q.js +0 -4
- package/dist/chunks/cf-settings-hbj16kh3.js +0 -4
- package/dist/chunks/color-thzpppyc.js +0 -4
- package/dist/chunks/components-a98hzqw9.js +0 -4
- package/dist/chunks/content-source-jq3fjs3w.js +0 -4
- package/dist/chunks/convert-to-repeater-g66r6qp1.js +0 -4
- package/dist/chunks/editor-rth1rzj8.js +0 -4
- package/dist/chunks/entry-commands-02j0s19w.js +0 -4
- package/dist/chunks/extension-sections-rqrs7dr0.js +0 -4
- package/dist/chunks/file-ops-6a49er4c.js +0 -4
- package/dist/chunks/files-b2p9y0yz.js +0 -4
- package/dist/chunks/format-host-7xe57k1s.js +0 -4
- package/dist/chunks/fs-events-0xsy168g.js +0 -4
- package/dist/chunks/grid-open-h3q4fjy5.js +0 -4
- package/dist/chunks/iframe-entry-m24fza30.js +0 -5
- package/dist/chunks/iframe-host-8jcmaktg.js +0 -4
- package/dist/chunks/index-7nj2375a.js +0 -4
- package/dist/chunks/jx-validate-808zgbgy.js +0 -4
- package/dist/chunks/layers-0ffdtqjn.js +0 -4
- package/dist/chunks/layers-panel-rw62wtvf.js +0 -4
- package/dist/chunks/lit-html-9bz9rcfv.js +0 -4
- package/dist/chunks/media-library-2a5hdbek.js +0 -4
- package/dist/chunks/media-open-069kzhj4.js +0 -4
- package/dist/chunks/media-picker-4p4pd28y.js +0 -4
- package/dist/chunks/monaco-buffer-m9fd2dka.js +0 -4
- package/dist/chunks/monaco-setup-e0crh3v6.js +0 -4
- package/dist/chunks/notify-re3js157.js +0 -4
- package/dist/chunks/parse-hee7ne9b.js +0 -4
- package/dist/chunks/platform-rywy3tkg.js +0 -4
- package/dist/chunks/publish-panel-czkpg8m4.js +0 -4
- package/dist/chunks/publish-quick-b9wbhqj6.js +0 -4
- package/dist/chunks/publish-workspace-yy6d23b7.js +0 -4
- package/dist/chunks/quick-search-tp7pjnmv.js +0 -4
- package/dist/chunks/references-wd2yj8s1.js +0 -4
- package/dist/chunks/right-panel-x971k0zc.js +0 -4
- package/dist/chunks/source-control-k4p00hpe.js +0 -4
- package/dist/chunks/studio-1d8m5s38.js +0 -16
- package/dist/chunks/studio-35pmfjtx.js +0 -5
- package/dist/chunks/studio-44xqe0b7.js +0 -4
- package/dist/chunks/studio-48yzqzqr.js +0 -5
- package/dist/chunks/studio-5rq3e4q5.js +0 -5
- package/dist/chunks/studio-6hcfm9q3.js +0 -5
- package/dist/chunks/studio-6mf31e16.js +0 -5
- package/dist/chunks/studio-8w5pa88p.js +0 -7
- package/dist/chunks/studio-9c6cbq2c.js +0 -4
- package/dist/chunks/studio-aaw7wxv8.js +0 -5
- package/dist/chunks/studio-afx9brsc.js +0 -5
- package/dist/chunks/studio-dmgh2rrj.js +0 -5
- package/dist/chunks/studio-erjccagy.js +0 -5
- package/dist/chunks/studio-ex1644g2.js +0 -5
- package/dist/chunks/studio-gw83z798.js +0 -7
- package/dist/chunks/studio-j52ks8q7.js +0 -5
- package/dist/chunks/studio-kefs4sz4.js +0 -5
- package/dist/chunks/studio-m3jrjfhy.js +0 -14
- package/dist/chunks/studio-n4pnf0sw.js +0 -5
- package/dist/chunks/studio-ncwx602y.js +0 -5
- package/dist/chunks/studio-nzp0sqjg.js +0 -5
- package/dist/chunks/studio-ph17an19.js +0 -5
- package/dist/chunks/studio-q509sqt8.js +0 -5
- package/dist/chunks/studio-s49y6m5b.js +0 -5
- package/dist/chunks/studio-t46rt6gx.js +0 -5
- package/dist/chunks/studio-veh91hjv.js +0 -5
- package/dist/chunks/studio-vswmz40d.js +0 -6
- package/dist/chunks/studio-w4mfaaam.js +0 -5
- package/dist/chunks/studio-x5py815g.js +0 -5
- package/dist/chunks/studio-z6s56dzz.js +0 -5
- package/dist/chunks/studio-ze1sm147.js +0 -7
- package/dist/chunks/studio-zn7ysyzb.js +0 -5
- package/dist/chunks/toast-w11qpkyz.js +0 -4
- package/dist/chunks/workspace-home-61n1jz3q.js +0 -4
- package/dist/chunks/workspace-sheek6zw.js +0 -4
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jx Notation in the Code view: a Monarch grammar, with TypeScript inside a multi-line raw string.
|
|
3
|
+
*
|
|
4
|
+
* Multi-line raw strings are where a `.jxn` file keeps code (`spec.md` §22.3), so highlighting one
|
|
5
|
+
* as TypeScript is the common case and not a guess about a particular file.
|
|
6
|
+
*
|
|
7
|
+
* @docs framework/concepts/jxn-files
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { languages } from "monaco-editor/editor";
|
|
11
|
+
|
|
12
|
+
/** The language id, as `monacoLangForPath` answers it. */
|
|
13
|
+
export const JXN_LANGUAGE_ID = "jxn";
|
|
14
|
+
|
|
15
|
+
/** Comments and brackets, which is what typing and folding need to know. */
|
|
16
|
+
export const JXN_LANGUAGE_CONFIGURATION: languages.LanguageConfiguration = {
|
|
17
|
+
autoClosingPairs: [
|
|
18
|
+
{ close: "}", open: "{" },
|
|
19
|
+
{ close: ")", open: "(" },
|
|
20
|
+
{ close: '"', open: '"' },
|
|
21
|
+
],
|
|
22
|
+
brackets: [
|
|
23
|
+
["{", "}"],
|
|
24
|
+
["(", ")"],
|
|
25
|
+
],
|
|
26
|
+
comments: { blockComment: ["/*", "*/"], lineComment: "//" },
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** The tokenizer. */
|
|
30
|
+
export const JXN_MONARCH: languages.IMonarchLanguage = {
|
|
31
|
+
defaultToken: "",
|
|
32
|
+
// Monarch otherwise starts in the first state listed, and these are sorted.
|
|
33
|
+
start: "root",
|
|
34
|
+
tokenizer: {
|
|
35
|
+
blockComment: [
|
|
36
|
+
[/[^/*]+/u, "comment"],
|
|
37
|
+
[/\/\*/u, "comment", "@push"],
|
|
38
|
+
[/\*\//u, "comment", "@pop"],
|
|
39
|
+
[/[/*]/u, "comment"],
|
|
40
|
+
],
|
|
41
|
+
quoted: [
|
|
42
|
+
[/[^\\"]+/u, "string"],
|
|
43
|
+
[/\\./u, "string.escape"],
|
|
44
|
+
[/"/u, "string", "@pop"],
|
|
45
|
+
],
|
|
46
|
+
quotedLines: [
|
|
47
|
+
[/"""/u, "string", "@pop"],
|
|
48
|
+
[/\\./u, "string.escape"],
|
|
49
|
+
[/./u, "string"],
|
|
50
|
+
],
|
|
51
|
+
raw: [
|
|
52
|
+
[/"#+/u, { cases: { "$0==$S2": { next: "@pop", token: "string" }, "@default": "string" } }],
|
|
53
|
+
[/[^"]+/u, "string"],
|
|
54
|
+
[/"/u, "string"],
|
|
55
|
+
],
|
|
56
|
+
rawLines: [
|
|
57
|
+
[
|
|
58
|
+
/"""#+/u,
|
|
59
|
+
{
|
|
60
|
+
cases: {
|
|
61
|
+
"$0==$S2": { next: "@pop", nextEmbedded: "@pop", token: "string.quote" },
|
|
62
|
+
"@default": "",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
[/[^"]+/u, ""],
|
|
67
|
+
[/"/u, ""],
|
|
68
|
+
],
|
|
69
|
+
root: [
|
|
70
|
+
[/\/\/.*$/u, "comment"],
|
|
71
|
+
[/\/\*/u, "comment", "@blockComment"],
|
|
72
|
+
[/\/-/u, "comment"],
|
|
73
|
+
[/\((?:array|fn|object|on|ref)\)/u, "type"],
|
|
74
|
+
[/\([^)\s]*\)/u, "invalid"],
|
|
75
|
+
[/#"""/u, { next: '@rawLines."""#', nextEmbedded: "typescript", token: "string.quote" }],
|
|
76
|
+
[/##+"""/u, { next: '@rawLines."""$0', nextEmbedded: "typescript", token: "string.quote" }],
|
|
77
|
+
[/#+"/u, { next: '@raw."$0', token: "string" }],
|
|
78
|
+
[/"""/u, "string", "@quotedLines"],
|
|
79
|
+
[/"/u, "string", "@quoted"],
|
|
80
|
+
[/#(?:true|false|null|inf|-inf|nan)\b/u, "keyword"],
|
|
81
|
+
[/[-+]?\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][-+]?\d+)?/u, "number"],
|
|
82
|
+
[/[{};]/u, "delimiter"],
|
|
83
|
+
[/\$[^\s=(){};"]*/u, "keyword"],
|
|
84
|
+
[/[^\s=(){};"#]+(?==)/u, "attribute.name"],
|
|
85
|
+
[/[^\s=(){};"#]+/u, "identifier"],
|
|
86
|
+
[/[=]/u, "delimiter"],
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** The part of Monaco's API registering a language uses. */
|
|
92
|
+
export type MonacoLanguages = Pick<
|
|
93
|
+
typeof languages,
|
|
94
|
+
"register" | "setLanguageConfiguration" | "setMonarchTokensProvider"
|
|
95
|
+
>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Teach Monaco the language.
|
|
99
|
+
*
|
|
100
|
+
* @param languages `monaco.languages`. Absent under a double of Monaco that has no language API,
|
|
101
|
+
* and there is nothing to teach then.
|
|
102
|
+
*/
|
|
103
|
+
export function registerJxnLanguage(languages?: MonacoLanguages): void {
|
|
104
|
+
if (!languages) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
languages.register({ extensions: [".jxn"], id: JXN_LANGUAGE_ID });
|
|
108
|
+
languages.setLanguageConfiguration(JXN_LANGUAGE_ID, JXN_LANGUAGE_CONFIGURATION);
|
|
109
|
+
languages.setMonarchTokensProvider(JXN_LANGUAGE_ID, JXN_MONARCH);
|
|
110
|
+
}
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* schema completion with it.
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
-
import "monaco-editor/editor";
|
|
38
|
+
import * as monacoApi from "monaco-editor/editor";
|
|
39
39
|
// Core widget, icons, tokenization.
|
|
40
40
|
import "monaco-editor/features/codeEditor/register";
|
|
41
41
|
import "monaco-editor/features/codicon/register";
|
|
@@ -83,6 +83,8 @@ import projectSchema from "@jxsuite/schema/project-schema.json";
|
|
|
83
83
|
import type { JsonObject } from "@jxsuite/schema/types";
|
|
84
84
|
import type { ProjectSchemasResponse } from "../types";
|
|
85
85
|
import { bundleUrl } from "./bundle-base";
|
|
86
|
+
import { PROJECT_FILE_NAME } from "@jxsuite/schema/project-file";
|
|
87
|
+
import { registerJxnLanguage } from "./jxn-language";
|
|
86
88
|
|
|
87
89
|
/* Re-exported for the modules that already imported it from here. New callers should reach for
|
|
88
90
|
`./model-uri` directly — it is Monaco-free, and importing this module loads the editor. */
|
|
@@ -150,6 +152,8 @@ if (documentFonts?.ready) {
|
|
|
150
152
|
});
|
|
151
153
|
}
|
|
152
154
|
|
|
155
|
+
registerJxnLanguage(monacoApi.languages);
|
|
156
|
+
|
|
153
157
|
/** Folder globs whose JSON files validate against the (per-project or core) document schema. */
|
|
154
158
|
const DOCUMENT_FILE_MATCH = [
|
|
155
159
|
"pages/*.json",
|
|
@@ -205,7 +209,7 @@ function applyJsonSchemas(documentSchema: JsonObject, projectJsonSchema: JsonObj
|
|
|
205
209
|
uri: "https://jxsuite.com/schema/v1",
|
|
206
210
|
},
|
|
207
211
|
{
|
|
208
|
-
fileMatch: [
|
|
212
|
+
fileMatch: [PROJECT_FILE_NAME],
|
|
209
213
|
schema: projectJsonSchema,
|
|
210
214
|
uri: "https://jxsuite.com/schema/project/v1",
|
|
211
215
|
},
|
|
@@ -61,6 +61,7 @@ import type {
|
|
|
61
61
|
ContributedSurfaceHandle,
|
|
62
62
|
ContributedView,
|
|
63
63
|
} from "../surfaces/settings-contributed";
|
|
64
|
+
import { projectConfigPath } from "../tabs/tab";
|
|
64
65
|
|
|
65
66
|
// ─── Contribution shape ───────────────────────────────────────────────────────
|
|
66
67
|
|
|
@@ -258,7 +259,7 @@ async function saveProjectConfig(base: string, rerender: () => void) {
|
|
|
258
259
|
fault, so it is a problem of its own rather than an error parked on the user's field. */
|
|
259
260
|
notify.warn(`Could not validate project.json — ${errorMessage(error)}`, {
|
|
260
261
|
key: "settings:validator",
|
|
261
|
-
path:
|
|
262
|
+
path: projectConfigPath(),
|
|
262
263
|
source: "Settings",
|
|
263
264
|
tier: "problem",
|
|
264
265
|
});
|
|
@@ -43,6 +43,7 @@ import { notify } from "../services/notify";
|
|
|
43
43
|
import { notifySettingsDocument } from "./section-registry";
|
|
44
44
|
import { updateSiteConfig } from "../site-context";
|
|
45
45
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
46
|
+
import { projectConfigPath } from "../tabs/tab";
|
|
46
47
|
|
|
47
48
|
/** The package an extension operation is running for, or null. */
|
|
48
49
|
let _inFlight: string | null = null;
|
|
@@ -168,7 +169,7 @@ export async function enableExtension(specifier: string): Promise<void> {
|
|
|
168
169
|
}
|
|
169
170
|
await updateSiteConfig({ extensions: [...enabledSpecifiers(), row.specifier] });
|
|
170
171
|
/* Set after the write resolved, so the latch never claims a file the write did not reach. */
|
|
171
|
-
_lastEnableWrote = installed ? [
|
|
172
|
+
_lastEnableWrote = installed ? [projectConfigPath(), "package.json"] : [projectConfigPath()];
|
|
172
173
|
} finally {
|
|
173
174
|
_inFlight = null;
|
|
174
175
|
notifySettingsDocument();
|
|
@@ -25,7 +25,7 @@ import { runActiveReported } from "../commands/run-reported";
|
|
|
25
25
|
import { getPlatform } from "../platform";
|
|
26
26
|
import { mountOverviewSurface } from "../surfaces/settings-overview";
|
|
27
27
|
import { previewAssetSrcFor } from "../canvas/asset-refs";
|
|
28
|
-
import {
|
|
28
|
+
import { projectConfigPath } from "../tabs/tab";
|
|
29
29
|
|
|
30
30
|
import type {
|
|
31
31
|
OverviewActions,
|
|
@@ -191,7 +191,7 @@ function values(container: HTMLElement): OverviewValues {
|
|
|
191
191
|
error: errors.get(container) ?? null,
|
|
192
192
|
favicon: readFavicon(cfg),
|
|
193
193
|
// `project.json` authored it, whatever tab is in front: the section is project-level.
|
|
194
|
-
faviconSrc: previewAssetSrcFor(readFavicon(cfg),
|
|
194
|
+
faviconSrc: previewAssetSrcFor(readFavicon(cfg), projectConfigPath()),
|
|
195
195
|
name: cfg.name ?? "",
|
|
196
196
|
stylesDisabled: command === undefined,
|
|
197
197
|
stylesTitle: command?.title ?? "",
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
} from "../commands/command-args";
|
|
30
30
|
import { notify } from "../services/notify";
|
|
31
31
|
import { projectState } from "../state";
|
|
32
|
-
import {
|
|
32
|
+
import { projectConfigPath } from "../tabs/tab";
|
|
33
33
|
import { lendProjectConfigLayout } from "../tabs/project-config";
|
|
34
34
|
import { focusPane, openTab, paneOfTab, workspace } from "../workspace/workspace";
|
|
35
35
|
import { workspaceHomeTabId } from "../workspace/workspace-ids";
|
|
@@ -211,7 +211,7 @@ export function showSettingsDocument(mode: string = shell.stylebook.view): Tab |
|
|
|
211
211
|
return null;
|
|
212
212
|
}
|
|
213
213
|
rememberStylesView(mode);
|
|
214
|
-
const existing = workspace.tabs.get(
|
|
214
|
+
const existing = workspace.tabs.get(projectConfigPath());
|
|
215
215
|
if (existing) {
|
|
216
216
|
for (const candidate of PROJECT_TAB_MODES.toReversed()) {
|
|
217
217
|
if (!existing.capabilities.modes.includes(candidate)) {
|
|
@@ -225,8 +225,8 @@ export function showSettingsDocument(mode: string = shell.stylebook.view): Tab |
|
|
|
225
225
|
const tab = openTab({
|
|
226
226
|
capabilities: { modes: [...PROJECT_TAB_MODES] },
|
|
227
227
|
document: state.projectConfig ?? {},
|
|
228
|
-
documentPath:
|
|
229
|
-
id:
|
|
228
|
+
documentPath: projectConfigPath(),
|
|
229
|
+
id: projectConfigPath(),
|
|
230
230
|
});
|
|
231
231
|
/* The mode is written here rather than left to the capability list, because `createTab` seeds
|
|
232
232
|
`session.ui.canvasMode` from the first non-preview mode, and a door over the same document has
|
|
@@ -303,7 +303,7 @@ export async function openProjectSettings(section?: string): Promise<void> {
|
|
|
303
303
|
Problem rather than a toast that erases itself. */
|
|
304
304
|
notify.warn(`Could not load extension settings sections — ${errorMessage(error)}`, {
|
|
305
305
|
key: "settings:sections",
|
|
306
|
-
path:
|
|
306
|
+
path: projectConfigPath(),
|
|
307
307
|
source: "Settings",
|
|
308
308
|
tier: "problem",
|
|
309
309
|
});
|
package/src/shell.ts
CHANGED
|
@@ -102,10 +102,10 @@ export const NAVIGATOR_PANEL_IDS = [
|
|
|
102
102
|
"files",
|
|
103
103
|
"search",
|
|
104
104
|
"i18n",
|
|
105
|
+
"insert",
|
|
105
106
|
"layers",
|
|
106
107
|
"data",
|
|
107
108
|
"packages",
|
|
108
|
-
"insert",
|
|
109
109
|
] as const;
|
|
110
110
|
|
|
111
111
|
export type NavigatorPanelId = (typeof NAVIGATOR_PANEL_IDS)[number];
|
package/src/studio.ts
CHANGED
|
@@ -118,6 +118,7 @@ import {
|
|
|
118
118
|
refreshFormats,
|
|
119
119
|
} from "./format/format-host";
|
|
120
120
|
import {
|
|
121
|
+
followOpenDocuments,
|
|
121
122
|
loadProject as _loadProject,
|
|
122
123
|
openProject as _openProject,
|
|
123
124
|
findHomePage,
|
|
@@ -295,11 +296,12 @@ import { focusPublishHome } from "./publish/publish-workspace";
|
|
|
295
296
|
import { registerI18nCommands } from "./i18n/i18n-commands";
|
|
296
297
|
import { convertToComponent } from "./editor/convert-to-component";
|
|
297
298
|
import type { GitDiffState } from "./types";
|
|
298
|
-
import { PROJECT_CONFIG_PATH } from "./tabs/tab";
|
|
299
299
|
import type { Tab } from "./tabs/tab";
|
|
300
300
|
import type { JxDocument, ProjectConfig } from "@jxsuite/schema/types";
|
|
301
301
|
import { setBundleBase } from "./services/bundle-base";
|
|
302
302
|
import { mountBootFailureTree, mountShellTree } from "./shell/tree";
|
|
303
|
+
import { PROJECT_FILE_NAME, isProjectConfigPath } from "@jxsuite/schema/project-file";
|
|
304
|
+
import { projectConfigPath } from "./tabs/tab";
|
|
303
305
|
|
|
304
306
|
// The bundler's `<link rel=modulepreload>` batching is installed on the module scope: before the
|
|
305
307
|
// First lazy `import()` of any surface that runs, so the palette's first open does not pay a
|
|
@@ -403,7 +405,7 @@ function setCanvasMode(tab: Tab | null, mode: string) {
|
|
|
403
405
|
}
|
|
404
406
|
tab.session.ui.canvasMode = mode;
|
|
405
407
|
// The Styles home view follows the author's own switches between Variables and Elements.
|
|
406
|
-
if (tab.documentPath
|
|
408
|
+
if (isProjectConfigPath(tab.documentPath)) {
|
|
407
409
|
rememberStylesView(mode);
|
|
408
410
|
}
|
|
409
411
|
}
|
|
@@ -1152,7 +1154,7 @@ if (_projectParam) {
|
|
|
1152
1154
|
*/
|
|
1153
1155
|
const named =
|
|
1154
1156
|
_urlParams.get("file") ||
|
|
1155
|
-
(siteCtx.fileRelPath && !siteCtx.fileRelPath
|
|
1157
|
+
(siteCtx.fileRelPath && !isProjectConfigPath(siteCtx.fileRelPath)
|
|
1156
1158
|
? siteCtx.fileRelPath
|
|
1157
1159
|
: null);
|
|
1158
1160
|
if (!named) {
|
|
@@ -1168,8 +1170,8 @@ if (_projectParam) {
|
|
|
1168
1170
|
fileRelPath = named ?? siteCtx.fileRelPath ?? _projectParam;
|
|
1169
1171
|
|
|
1170
1172
|
// When opening project.json, default to home page instead (listing-based, no 404 probes).
|
|
1171
|
-
if (fileRelPath
|
|
1172
|
-
fileRelPath = (await findHomePage()) ??
|
|
1173
|
+
if (isProjectConfigPath(fileRelPath) || fileRelPath.endsWith(`/${PROJECT_FILE_NAME}`)) {
|
|
1174
|
+
fileRelPath = (await findHomePage()) ?? projectConfigPath();
|
|
1173
1175
|
}
|
|
1174
1176
|
|
|
1175
1177
|
const content = await platform.readFile(fileRelPath);
|
|
@@ -1205,7 +1207,7 @@ if (_projectParam) {
|
|
|
1205
1207
|
if (parsedMode === "content" && activeTab.value) {
|
|
1206
1208
|
activeTab.value.doc.mode = "content";
|
|
1207
1209
|
}
|
|
1208
|
-
if (fileRelPath
|
|
1210
|
+
if (isProjectConfigPath(fileRelPath) && activeTab.value) {
|
|
1209
1211
|
activeTab.value.session.ui.canvasMode = "stylebook";
|
|
1210
1212
|
}
|
|
1211
1213
|
|
|
@@ -1228,7 +1230,8 @@ if (_projectParam) {
|
|
|
1228
1230
|
}
|
|
1229
1231
|
} else {
|
|
1230
1232
|
// Normal mode: probe for project at server root
|
|
1231
|
-
|
|
1233
|
+
// oxlint-disable-next-line unicorn/prefer-top-level-await -- deliberate fire-and-forget: the shell renders first
|
|
1234
|
+
void loadProjectAndFollowDocuments();
|
|
1232
1235
|
render();
|
|
1233
1236
|
ensureFsSync();
|
|
1234
1237
|
}
|
|
@@ -1296,6 +1299,12 @@ function renderLeftPanel() {
|
|
|
1296
1299
|
leftPanelMod.render();
|
|
1297
1300
|
}
|
|
1298
1301
|
|
|
1302
|
+
/** Load what this window holds, then show what the operating system asks of it from here on. */
|
|
1303
|
+
async function loadProjectAndFollowDocuments() {
|
|
1304
|
+
await loadProject();
|
|
1305
|
+
followOpenDocuments();
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1299
1308
|
function loadProject() {
|
|
1300
1309
|
return _loadProject();
|
|
1301
1310
|
}
|
|
@@ -1334,7 +1343,10 @@ async function openProject(target: ProjectOpenTarget = "thisWindow"): Promise<Pr
|
|
|
1334
1343
|
if (!picked) {
|
|
1335
1344
|
return "cancelled";
|
|
1336
1345
|
}
|
|
1337
|
-
const { focused } = await platform.openProjectInNewWindow(picked.root);
|
|
1346
|
+
const { declined, focused } = await platform.openProjectInNewWindow(picked.root);
|
|
1347
|
+
if (declined) {
|
|
1348
|
+
return "cancelled";
|
|
1349
|
+
}
|
|
1338
1350
|
return focused ? "focused" : "newWindow";
|
|
1339
1351
|
}
|
|
1340
1352
|
// The SECOND destroyer, and it was ungated for as long as the first one was. `openRecentProject`
|
|
@@ -1394,8 +1406,8 @@ async function openRecentProject(root: string) {
|
|
|
1394
1406
|
// Multi-window (desktop): if this window already holds a project, open the chosen one in a new
|
|
1395
1407
|
// Window (focusing an existing window if it's already open) rather than replacing this project.
|
|
1396
1408
|
if (projectState && platform.openProjectInNewWindow) {
|
|
1397
|
-
await platform.openProjectInNewWindow(root);
|
|
1398
|
-
activity.done("Opened in another window");
|
|
1409
|
+
const { declined } = await platform.openProjectInNewWindow(root);
|
|
1410
|
+
activity.done(declined ? "Didn't open the project" : "Opened in another window");
|
|
1399
1411
|
return;
|
|
1400
1412
|
}
|
|
1401
1413
|
|
|
@@ -1420,6 +1432,11 @@ async function openRecentProject(root: string) {
|
|
|
1420
1432
|
// The project is already open in another window, that window is focused and we bail here.
|
|
1421
1433
|
if (platform.setWindowProject) {
|
|
1422
1434
|
const res = await platform.setWindowProject(root);
|
|
1435
|
+
if (res.declined) {
|
|
1436
|
+
// The user declined to run its code, and nothing has moved yet: the tabs above stay open.
|
|
1437
|
+
activity.done("Kept the current project");
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1423
1440
|
if (res.deduped) {
|
|
1424
1441
|
activity.done("Already open in another window");
|
|
1425
1442
|
return;
|
|
@@ -1439,7 +1456,7 @@ async function openRecentProject(root: string) {
|
|
|
1439
1456
|
refreshFormats();
|
|
1440
1457
|
void loadFormats();
|
|
1441
1458
|
refreshExtensionUi(platform);
|
|
1442
|
-
const content = await platform.readFile(
|
|
1459
|
+
const content = await platform.readFile(projectConfigPath());
|
|
1443
1460
|
/* SAFETY: This is `project.json` at the root the user chose to open, the project's own config
|
|
1444
1461
|
file whose schema is ProjectConfig; Studio edits it in that shape and does not re-validate it
|
|
1445
1462
|
on open, as the folder-picker path in `platforms/devserver.ts` does not either. */
|
|
@@ -36,7 +36,7 @@ import { projectState } from "../store";
|
|
|
36
36
|
import { shell } from "../shell";
|
|
37
37
|
import { runActiveReported } from "../commands/run-reported";
|
|
38
38
|
import { projectConfigDocument } from "../tabs/project-config";
|
|
39
|
-
import {
|
|
39
|
+
import { isProjectConfigPath } from "../tabs/tab";
|
|
40
40
|
import { paneRegion } from "../ui/regions";
|
|
41
41
|
import { focusCssVar, focusCssVarGroup, renderCssVarsEditor } from "../settings/css-vars-editor";
|
|
42
42
|
import { variablesFocus } from "./variables-focus";
|
|
@@ -126,7 +126,7 @@ function manageContexts(): void {
|
|
|
126
126
|
* place is the tab's own. A no-op with no project, and for any other document.
|
|
127
127
|
*/
|
|
128
128
|
function bindConfiguration(tab: Tab): void {
|
|
129
|
-
if (projectState && tab.documentPath
|
|
129
|
+
if (projectState && isProjectConfigPath(tab.documentPath)) {
|
|
130
130
|
projectConfigDocument();
|
|
131
131
|
}
|
|
132
132
|
}
|