@jxsuite/studio 10.1.0 → 10.3.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/dist/chunks/{2020-mkb0qa6p.js → 2020-906vx2dq.js} +3 -3
- package/dist/chunks/adapter-hnvad61x.js +4 -0
- package/dist/chunks/add-new-flow-3tkn72ey.js +4 -0
- package/dist/chunks/cf-account-picker-xb8vvt2h.js +4 -0
- package/dist/chunks/cf-settings-mkbcz4z2.js +4 -0
- package/dist/chunks/components-w5zqwva1.js +4 -0
- package/dist/chunks/content-source-1vzxq1ba.js +4 -0
- package/dist/chunks/convert-to-repeater-gwzh9gar.js +4 -0
- package/dist/chunks/editor-wvf5e6j9.js +4 -0
- package/dist/chunks/entry-commands-mx2whrjx.js +4 -0
- package/dist/chunks/extension-sections-338ee35t.js +4 -0
- package/dist/chunks/file-ops-9bxvk59j.js +4 -0
- package/dist/chunks/files-t07yqqej.js +4 -0
- package/dist/chunks/format-host-5ja5gxyk.js +4 -0
- package/dist/chunks/fs-events-3424ezp3.js +4 -0
- package/dist/chunks/grid-open-1mpq9mzb.js +4 -0
- package/dist/chunks/{grid-view-r22jsqht.js → grid-view-w9nfy203.js} +15 -15
- package/dist/chunks/icons-gb967qc8.js +4 -0
- package/dist/chunks/iframe-host-wsg0bn73.js +4 -0
- package/dist/chunks/image-bake-4afr4y6a.js +4 -0
- package/dist/chunks/image-editor-x7t8jbjn.js +4 -0
- package/dist/chunks/index-f9qr7kzh.js +4 -0
- package/dist/chunks/{index-pxwwf00y.js → index-yjrfeks8.js} +3 -3
- package/dist/chunks/{javascript-pzqryby6.js → javascript-hy2mws8v.js} +3 -3
- package/dist/chunks/{jsonMode-tcnyxyap.js → jsonMode-vj30te2h.js} +6 -6
- package/dist/chunks/jx-validate-ttr5ewf0.js +4 -0
- package/dist/chunks/layers-m49nmwvx.js +4 -0
- package/dist/chunks/layers-panel-hvy2e549.js +4 -0
- package/dist/chunks/lit-html-k2mb9k0r.js +4 -0
- package/dist/chunks/media-library-ae67q4at.js +4 -0
- package/dist/chunks/media-open-yp9jm834.js +4 -0
- package/dist/chunks/media-picker-s41ngdfr.js +4 -0
- package/dist/chunks/{monaco-binding-bqpge64f.js → monaco-binding-a51py33c.js} +3 -3
- package/dist/chunks/monaco-buffer-pa0g6ax7.js +4 -0
- package/dist/chunks/{monaco-setup-1mkab762.js → monaco-setup-g9kterhx.js} +3 -3
- package/dist/chunks/notify-bwehrp7q.js +4 -0
- package/dist/chunks/parse-hee7ne9b.js +4 -0
- package/dist/chunks/platform-kv0k65cy.js +4 -0
- package/dist/chunks/publish-panel-gzfxcm0t.js +4 -0
- package/dist/chunks/publish-quick-w3nxd7q4.js +4 -0
- package/dist/chunks/publish-workspace-dppd82tc.js +4 -0
- package/dist/chunks/quick-search-tdxaam55.js +4 -0
- package/dist/chunks/references-vqyr5s9x.js +4 -0
- package/dist/chunks/right-panel-0yrw4cgz.js +4 -0
- package/dist/chunks/source-control-6fk72me2.js +4 -0
- package/dist/chunks/{studio-0g2sm01j.js → studio-0939t1q1.js} +4 -4
- package/dist/chunks/studio-0gvvqj3h.js +5 -0
- package/dist/chunks/studio-0khd8xtx.js +4 -0
- package/dist/chunks/{studio-rf8d6p9f.js → studio-0w3541dg.js} +6 -6
- package/dist/chunks/{studio-9b7177jq.js → studio-0x6f3nk9.js} +4 -4
- package/dist/chunks/studio-1410q5dw.js +5 -0
- package/dist/chunks/{studio-8qejv8yf.js → studio-15hwqgd8.js} +4 -4
- package/dist/chunks/studio-1ks5d9y4.js +5 -0
- package/dist/chunks/{studio-881z1xrx.js → studio-2ggfzrrd.js} +4 -4
- package/dist/chunks/{studio-jw0q5j6k.js → studio-321ym1tt.js} +4 -4
- package/dist/chunks/studio-3c10v2q1.js +5 -0
- package/dist/chunks/{studio-9rcbvksg.js → studio-3na1r48j.js} +8 -8
- package/dist/chunks/{studio-ggm7zf70.js → studio-3q7mhbgx.js} +5 -5
- package/dist/chunks/studio-3qr08sxq.js +4 -0
- package/dist/chunks/studio-3xk9zdgb.js +5 -0
- package/dist/chunks/studio-423tfdte.js +5 -0
- package/dist/chunks/{studio-brdp85q7.js → studio-45mj4jqe.js} +4 -4
- package/dist/chunks/studio-4f7thq0p.js +5 -0
- package/dist/chunks/{studio-w67vfgy5.js → studio-4fnb5648.js} +4 -4
- package/dist/chunks/studio-4zd6an2b.js +5 -0
- package/dist/chunks/studio-53wy9ek3.js +5 -0
- package/dist/chunks/studio-5n193zqd.js +5 -0
- package/dist/chunks/{studio-x2metr13.js → studio-5tet77de.js} +3 -3
- package/dist/chunks/studio-7rrdbvex.js +5 -0
- package/dist/chunks/studio-8kx6m0rg.js +5 -0
- package/dist/chunks/{studio-va0e63sk.js → studio-90zkgne5.js} +7 -7
- package/dist/chunks/studio-9c6cbq2c.js +4 -0
- package/dist/chunks/studio-9dq7rwc7.js +5 -0
- package/dist/chunks/studio-9qx1ywbv.js +9 -0
- package/dist/chunks/studio-a65kbs2e.js +9 -0
- package/dist/chunks/studio-aam8zt8z.js +5 -0
- package/dist/chunks/{studio-8jb31dcf.js → studio-abh9kfdh.js} +4 -4
- package/dist/chunks/studio-b4e0ftkt.js +5 -0
- package/dist/chunks/studio-b68k0z00.js +5 -0
- package/dist/chunks/{studio-dy2xtt7a.js → studio-bct64zmj.js} +4 -4
- package/dist/chunks/studio-bz0b5brj.js +6 -0
- package/dist/chunks/studio-cfnn70h1.js +5 -0
- package/dist/chunks/studio-daksw8kh.js +5 -0
- package/dist/chunks/{studio-mwnmzx7g.js → studio-e7vjyp04.js} +7 -7
- package/dist/chunks/studio-ea6r1zyr.js +5 -0
- package/dist/chunks/studio-egnjpyde.js +9 -0
- package/dist/chunks/studio-ejrypvmq.js +5 -0
- package/dist/chunks/studio-eqcddvc2.js +928 -0
- package/dist/chunks/studio-f8tyeyzt.js +5 -0
- package/dist/chunks/studio-fj6c905s.js +5 -0
- package/dist/chunks/{studio-hsr3k06v.js → studio-fkrr7kgg.js} +5 -5
- package/dist/chunks/studio-fspe7m9t.js +5 -0
- package/dist/chunks/{studio-4zqfw5ha.js → studio-g0hxtcga.js} +4 -4
- package/dist/chunks/studio-g9brbewz.js +5 -0
- package/dist/chunks/studio-ggx3j7nd.js +5 -0
- package/dist/chunks/{studio-jh6t5qz4.js → studio-hfxttkyr.js} +4 -4
- package/dist/chunks/studio-hh394phe.js +5 -0
- package/dist/chunks/{studio-07k0geap.js → studio-j0zf5x2x.js} +4 -4
- package/dist/chunks/studio-jeb7hth3.js +5 -0
- package/dist/chunks/studio-k0xzrse2.js +64 -0
- package/dist/chunks/studio-k1xqrgm5.js +5 -0
- package/dist/chunks/studio-k2evngrj.js +7 -0
- package/dist/chunks/studio-k3we3kqb.js +5 -0
- package/dist/chunks/{studio-nf0pqpbj.js → studio-n9qba0gx.js} +4 -4
- package/dist/chunks/studio-nf8esxxc.js +5 -0
- package/dist/chunks/studio-nn4f9m9c.js +5 -0
- package/dist/chunks/studio-nskxe9q1.js +6 -0
- package/dist/chunks/{studio-4nkm4404.js → studio-nvcn2ykc.js} +4 -4
- package/dist/chunks/studio-nwynxqtb.js +5 -0
- package/dist/chunks/{studio-f2j9et3h.js → studio-nzemfbkk.js} +8 -8
- package/dist/chunks/studio-p2a03pgm.js +5 -0
- package/dist/chunks/{studio-skynbac3.js → studio-pm17wdc4.js} +4 -4
- package/dist/chunks/{studio-9cp96v90.js → studio-q80fg1d6.js} +7 -7
- package/dist/chunks/studio-r050sez0.js +6 -0
- package/dist/chunks/{studio-sd07xva5.js → studio-s7t4vp1d.js} +5 -5
- package/dist/chunks/studio-s9fng7m8.js +7 -0
- package/dist/chunks/studio-sce30r7b.js +4 -0
- package/dist/chunks/{studio-zxm98z2m.js → studio-stahswgb.js} +6 -6
- package/dist/chunks/studio-swedpd82.js +5 -0
- package/dist/chunks/studio-thz5t120.js +5 -0
- package/dist/chunks/studio-tpxcryf2.js +5 -0
- package/dist/chunks/{studio-tpy3rdxn.js → studio-v5wktj6f.js} +4 -4
- package/dist/chunks/{studio-7vb997ff.js → studio-vpevkfxw.js} +4 -4
- package/dist/chunks/studio-waekn290.js +5 -0
- package/dist/chunks/studio-wfct4h6n.js +5 -0
- package/dist/chunks/studio-wgc54sxf.js +5 -0
- package/dist/chunks/studio-wqfaqw4m.js +5 -0
- package/dist/chunks/studio-wse1rs8t.js +7 -0
- package/dist/chunks/studio-x0gsfr1d.js +16 -0
- package/dist/chunks/studio-xpx91fby.js +6 -0
- package/dist/chunks/studio-y1b86ast.js +5 -0
- package/dist/chunks/studio-yrcrncev.js +5 -0
- package/dist/chunks/{studio-zacvfm31.js → studio-yzpskb0j.js} +4 -4
- package/dist/chunks/studio-zfdbmhp3.js +5 -0
- package/dist/chunks/{tsMode-6vwhy6ty.js → tsMode-jg1dtphj.js} +7 -7
- package/dist/chunks/workspace-9btkc8tk.js +4 -0
- package/dist/chunks/workspace-home-qcc4z5ag.js +4 -0
- package/dist/chunks/{ws-client-zcxkfgmf.js → ws-client-arz2qsy9.js} +3 -3
- package/dist/iframe-entry.js +13 -13
- package/dist/manifest.json +83 -77
- package/dist/studio.js +74 -75
- package/package.json +5 -5
- package/src/browse/library-model.ts +56 -23
- package/src/browse/library-pane.ts +44 -29
- package/src/browse/library-preview.ts +6 -2
- package/src/canvas/asset-refs.ts +13 -4
- package/src/canvas/asset-resolve.ts +54 -11
- package/src/canvas/canvas-render.ts +25 -0
- package/src/canvas/iframe-entry.ts +5 -1
- package/src/canvas/iframe-host.ts +16 -6
- package/src/canvas/iframe-protocol.ts +9 -1
- package/src/commands/context.ts +6 -0
- package/src/commands/live-context.ts +5 -2
- package/src/editor/shortcuts.ts +6 -0
- package/src/files/asset-versions.ts +108 -2
- package/src/files/file-ops.ts +11 -1
- package/src/files/files.ts +111 -48
- package/src/files/media-paths.ts +12 -4
- package/src/files/media-upload.ts +195 -21
- package/src/files/new-file-name.ts +39 -1
- package/src/media/image-bake.ts +164 -0
- package/src/media/image-editor.ts +846 -0
- package/src/media/image-format.ts +262 -0
- package/src/media/image-recipe.ts +651 -0
- package/src/media/media-commands.ts +65 -1
- package/src/media/media-library-model.ts +1 -1
- package/src/media/media-library.ts +175 -15
- package/src/media/media-open.ts +156 -3
- package/src/media/media-pane.ts +8 -4
- package/src/panels/data-grid.ts +0 -4
- package/src/panels/pane-context.ts +6 -1
- package/src/panels/settings-menu.ts +3 -3
- package/src/panels/settings-pane.ts +42 -56
- package/src/panels/tab-strip.ts +12 -3
- package/src/services/ai-import-tools.ts +6 -3
- package/src/services/ai-models.ts +65 -11
- package/src/services/ai-settings.ts +45 -5
- package/src/services/document-assistant.ts +5 -2
- package/src/services/settings/definitions.ts +19 -0
- package/src/settings/contributed-section.ts +16 -7
- package/src/settings/css-vars-editor.ts +4 -4
- package/src/settings/general-settings.ts +1 -4
- package/src/settings/preferences-accounts.ts +2 -2
- package/src/settings/preferences-dialog.ts +4 -2
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/section-registry.ts +5 -4
- package/src/settings/settings-document.ts +33 -24
- package/src/settings/settings-workspace.ts +205 -0
- package/src/shell.ts +31 -6
- package/src/studio.ts +13 -2
- package/src/surfaces/ai-credentials-form.json +59 -5
- package/src/surfaces/ai-credentials-form.ts +15 -2
- package/src/surfaces/commandbar.ts +7 -3
- package/src/surfaces/image-editor.json +1390 -0
- package/src/surfaces/image-editor.ts +272 -0
- package/src/surfaces/media-library.json +129 -1
- package/src/surfaces/media-library.ts +17 -2
- package/src/surfaces/settings-contributed.json +4 -4
- package/src/surfaces/settings-contributed.ts +2 -2
- package/src/surfaces/settings-pane.json +262 -180
- package/src/surfaces/settings-pane.ts +63 -14
- package/src/types.ts +2 -1
- package/src/ui/ai-credentials-form.ts +128 -11
- package/src/ui/regions.ts +5 -5
- package/src/workspace/tab-workspace.ts +5 -3
- package/src/workspace/workspace-home.ts +18 -4
- package/src/workspace/workspace-ids.ts +40 -7
- package/src/workspace/workspace-switch.ts +3 -1
- package/src/workspace/workspace.ts +22 -1
- package/dist/chunks/adapter-xcpsmecx.js +0 -4
- package/dist/chunks/add-new-flow-ptmhmzr9.js +0 -4
- package/dist/chunks/cf-account-picker-z1sgwpwd.js +0 -4
- package/dist/chunks/cf-settings-xqvhxxe9.js +0 -4
- package/dist/chunks/components-whsc81a7.js +0 -4
- package/dist/chunks/content-source-jwtxg78w.js +0 -4
- package/dist/chunks/convert-to-repeater-f92ey3kp.js +0 -4
- package/dist/chunks/editor-zdqdpq1x.js +0 -4
- package/dist/chunks/entry-commands-w8p2fbpt.js +0 -4
- package/dist/chunks/extension-sections-y2p1te2r.js +0 -4
- package/dist/chunks/file-ops-13ab4swj.js +0 -4
- package/dist/chunks/files-zbc8p6v1.js +0 -4
- package/dist/chunks/format-host-zjsbktbx.js +0 -4
- package/dist/chunks/fs-events-t6x0hch6.js +0 -4
- package/dist/chunks/grid-open-fyzdwpkh.js +0 -4
- package/dist/chunks/icons-853n6qt3.js +0 -4
- package/dist/chunks/iframe-host-kbyqc7pt.js +0 -4
- package/dist/chunks/index-6nvj89vb.js +0 -4
- package/dist/chunks/jx-validate-5sp8a4rm.js +0 -4
- package/dist/chunks/layers-panel-qrxj9vr2.js +0 -4
- package/dist/chunks/layers-tpzayggx.js +0 -4
- package/dist/chunks/lit-html-x6nrxsx3.js +0 -4
- package/dist/chunks/media-library-ywppnjrz.js +0 -4
- package/dist/chunks/media-picker-etxgc8qq.js +0 -4
- package/dist/chunks/monaco-buffer-qrnqhk0b.js +0 -4
- package/dist/chunks/notify-kcv38wwe.js +0 -4
- package/dist/chunks/parse-df2kkmhc.js +0 -4
- package/dist/chunks/platform-dtsysmyd.js +0 -4
- package/dist/chunks/publish-panel-evb1rcxt.js +0 -4
- package/dist/chunks/publish-quick-m9vkhahq.js +0 -4
- package/dist/chunks/publish-workspace-ktk9h536.js +0 -4
- package/dist/chunks/quick-search-2f47fxcw.js +0 -4
- package/dist/chunks/references-5w6ajjv7.js +0 -4
- package/dist/chunks/right-panel-kz0a6byf.js +0 -4
- package/dist/chunks/source-control-1phx90zk.js +0 -4
- package/dist/chunks/studio-0hr000ba.js +0 -5
- package/dist/chunks/studio-1wyp7dt5.js +0 -5
- package/dist/chunks/studio-20ap8dds.js +0 -5
- package/dist/chunks/studio-291gqh98.js +0 -5
- package/dist/chunks/studio-37twdaf7.js +0 -64
- package/dist/chunks/studio-4smcnv33.js +0 -5
- package/dist/chunks/studio-56egy6vf.js +0 -5
- package/dist/chunks/studio-5dmgmyw4.js +0 -5
- package/dist/chunks/studio-5e7p1vgd.js +0 -5
- package/dist/chunks/studio-5m0w815d.js +0 -5
- package/dist/chunks/studio-695k95bw.js +0 -5
- package/dist/chunks/studio-6vwvshw8.js +0 -6
- package/dist/chunks/studio-732mw0g8.js +0 -5
- package/dist/chunks/studio-76t560kn.js +0 -6
- package/dist/chunks/studio-7823f0g8.js +0 -5
- package/dist/chunks/studio-8486jn4r.js +0 -5
- package/dist/chunks/studio-848rk4p1.js +0 -5
- package/dist/chunks/studio-8x8616xd.js +0 -5
- package/dist/chunks/studio-a3s6frde.js +0 -4
- package/dist/chunks/studio-ahf3cspq.js +0 -4
- package/dist/chunks/studio-bkmv1h3e.js +0 -9
- package/dist/chunks/studio-cgb97rwv.js +0 -5
- package/dist/chunks/studio-ch8gt8vt.js +0 -5
- package/dist/chunks/studio-cqf1k4qk.js +0 -5
- package/dist/chunks/studio-cvz0e00f.js +0 -5
- package/dist/chunks/studio-dbgv4fv9.js +0 -16
- package/dist/chunks/studio-eesyjg7h.js +0 -9
- package/dist/chunks/studio-et6t8g4m.js +0 -4
- package/dist/chunks/studio-fep7hr66.js +0 -7
- package/dist/chunks/studio-fyf7j57j.js +0 -5
- package/dist/chunks/studio-g5prntab.js +0 -5
- package/dist/chunks/studio-ga77mf07.js +0 -5
- package/dist/chunks/studio-h7gy12h2.js +0 -5
- package/dist/chunks/studio-j933k8nr.js +0 -5
- package/dist/chunks/studio-jgbvqcgh.js +0 -5
- package/dist/chunks/studio-k4xc5g6h.js +0 -5
- package/dist/chunks/studio-p0nf2e1f.js +0 -6
- package/dist/chunks/studio-pd9dsqpq.js +0 -5
- package/dist/chunks/studio-pmzg17fj.js +0 -5
- package/dist/chunks/studio-pzfa2vmb.js +0 -5
- package/dist/chunks/studio-qyb5bebs.js +0 -9
- package/dist/chunks/studio-rt498t2v.js +0 -5
- package/dist/chunks/studio-s0fg2wav.js +0 -5
- package/dist/chunks/studio-t3j8htp7.js +0 -7
- package/dist/chunks/studio-thj81e98.js +0 -7
- package/dist/chunks/studio-tyw7tk0x.js +0 -5
- package/dist/chunks/studio-vcz63n42.js +0 -5
- package/dist/chunks/studio-vffwe9k7.js +0 -5
- package/dist/chunks/studio-vjhej0w5.js +0 -928
- package/dist/chunks/studio-vxjap704.js +0 -5
- package/dist/chunks/studio-xebavr9s.js +0 -5
- package/dist/chunks/studio-yg5n49za.js +0 -5
- package/dist/chunks/studio-yhz5b313.js +0 -5
- package/dist/chunks/studio-zsjpsw08.js +0 -5
- package/dist/chunks/workspace-d65bz1qk.js +0 -4
- package/dist/chunks/workspace-home-vbg9b3jh.js +0 -4
- package/src/settings/settings-dialog.ts +0 -192
- package/src/surfaces/settings-dialog.json +0 -51
- package/src/surfaces/settings-dialog.ts +0 -169
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{ee}from"./studio-et6t8g4m.js";import{aI,p,_e}from"./studio-w67vfgy5.js";import{Ys,nn}from"./studio-5dmgmyw4.js";import{fn}from"./studio-848rk4p1.js";import{Tn,m,h,_i,jt}from"./studio-j933k8nr.js";import{g,ar,C}from"./studio-ahf3cspq.js";import{Ot,Nt}from"./studio-f2j9et3h.js";import{Nw}from"./studio-5m0w815d.js";import{u}from"./studio-dbgv4fv9.js";import{Ue,ft,T,R,Yt,tt,qo,Qn,g$}from"./studio-cvz0e00f.js";import{hS}from"./studio-fep7hr66.js";import{Us,sN,el}from"./studio-qyb5bebs.js";import{ui,wm,Vl,pL,mL,Ab}from"./studio-695k95bw.js";import{GD}from"./studio-tyw7tk0x.js";import{KO,S,ZO,sr}from"./studio-rt498t2v.js";import{n,Q,_,v}from"./studio-zsjpsw08.js";import{le}from"./studio-0g2sm01j.js";var wt={children:[],tagName:"div"},vt=new Set(["bunfig.json","jsconfig.json","package-lock.json","package.json","tsconfig.json","wrangler.json"]);function bb(t){let e=t.slice(t.lastIndexOf("/")+1);if(vt.has(e)||e.endsWith(".schema.json"))return!1;return t.endsWith(".json")||Boolean(fn(t))}function B(t,e){if(t.startsWith("../")||t.includes("/../"))return`"${t}" is outside this project, so its comparison belongs to the project that owns it.`;if(e==="R")return"A renamed file's comparison needs both paths, and Studio does not model the old name yet.";if(Nw(t))return`"${t}" is an image or media file, and a comparison of one is not text.`;return null}function xt(){return["git-diff"]}function Pt(t){let e=m.tabs.get(t);if(e)return jt(t),e;return _i({capabilities:{modes:xt()},document:structuredClone(wt),documentPath:t,id:t,sourceFormat:null})}async function V(t){if(!bb(t))return Pt(t);let e=await (le("zbc8p6v1"),import("./files-zbc8p6v1.js"));return await e.openFileInTab(t,{canvasMode:"git-diff"}),[...m.tabs.values()].find((o)=>o.documentPath===t)??null}var W={$schema:"https://jxsuite.com/schema/v1",$id:"StudioGithubPublish",$description:"Create GitHub Repository: the three things the flow needs before it calls the API — the repository's name, an optional description, and whether it is private. A `jx-dialog`, so the platform owns modality, Escape, focus restoration and the backdrop, and the kit draws both answer buttons. Nothing here reaches GitHub: `github/github-publish.ts` keeps the token, the request and the activity, and this document only collects.",tagName:"jx-dialog",$props:{headline:"Create GitHub Repository",confirmLabel:"Create Repository",cancelLabel:"Cancel",size:"sm"},attributes:{part:"github-publish"},onconfirm:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirm"},value:[]}]},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancel"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},style:{$description:'What is NOT here is most of the conversion. `.github-publish-dialog` was a flex column with an 8px gap and `8px 0` of padding: the gap is the one thing it said that nothing else draws, and `jx-dialog`\'s own body already pads the content, so only the gap survives. `.github-publish-dialog sp-textfield { width: 100% }` had nothing to transcribe either — a `jx-field` row is a grid whose control cell stretches, so the field fills the row without being told to. The three `sp-field-label`s are gone with them, because `jx-field` draws the label AND names the control from it; the third of them carried no `for` at all, so "Visibility" was text beside a switch rather than a name for it.','& [part="rows"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)"}},children:[{tagName:"div",attributes:{part:"rows"},children:[{tagName:"jx-field",$props:{span:!0,label:"Repository name"},attributes:{part:"row","data-field":"name"},children:[{tagName:"jx-textfield",$props:{placeholder:"my-project",value:{$ref:"#/state/name"}},attributes:{part:"field"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setName"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"Description (optional)"},attributes:{part:"row","data-field":"description"},children:[{tagName:"jx-textfield",$props:{placeholder:"A brief description",value:{$ref:"#/state/description"}},attributes:{part:"field"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setDescription"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"Visibility"},attributes:{part:"row","data-field":"visibility"},children:[{tagName:"div",$description:'The row opens with a plain `div`, and that is the whole reason it exists: `jx-field` names the first thing slotted into it that observes `labelledby`, so a switch slotted straight in would be announced "Visibility" over the top of the words printed beside it. A `div` observes no naming, so the switch keeps the name its own label gives it.',attributes:{part:"visibility-row"},children:[{tagName:"jx-switch",attributes:{part:"toggle"},$props:{checked:{$ref:"#/state/isPrivate"}},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setPrivate"},value:[{$ref:"event#/target/checked"}]}]},children:[{tagName:"span",textContent:"Private repository"}]}]}]}]}]};T("github-publish",W);function q(t){let e=document.createElement("div");e.style.pointerEvents="auto",e.setAttribute(Ue,ft("dialog","github-publish")),t.layer.append(e);let o=!1,r=()=>{if(o)return;o=!0,t.onClosed()},i=()=>o,a=g({cancel:()=>{t.onCancel()},closed:r,confirm:()=>{t.onConfirm({description:a.description,isPrivate:a.isPrivate,name:a.name})},description:"",isPrivate:!0,name:t.name,setDescription:(l)=>{a.description=l},setName:(l)=>{a.name=l},setPrivate:(l)=>{a.isPrivate=l}}),s=null,d=R("github-publish",a,e).then(async(l)=>{s=l;let f=l.root;if(i())return l.dispose(),f;if(await Yt(f),i())return f;return Ot(f),f});return{close(){if(o)return;let l=s?.root;if(l instanceof HTMLElement)Nt(l);s?.dispose(),s=null,e.remove(),r()},host:e,ready:d}}var k=["Create the repository","Add the remote","Push"];function Ct(t){return new Promise((e)=>{let o=!1,r=(a)=>{if(o)return;o=!0,e(a)},i=q({layer:tt("dialog"),name:t,onCancel:()=>{i.close()},onClosed:()=>{r(null)},onConfirm:(a)=>{r({...a,name:a.name||t}),i.close()}})})}async function z({projectName:t}){let e=await hS();if(!e)return!1;let o=await Ct(t);if(!o)return!1;let r=Us({source:"Source Control",status:`Creating ${o.name}…`,steps:[...k],title:"Create GitHub repository"});r.step(k[0]);let i;try{i=await fetch("https://api.github.com/user/repos",{body:JSON.stringify({auto_init:!1,description:o.description,name:o.name,private:o.isPrivate}),headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${e}`,"Content-Type":"application/json"},method:"POST"})}catch(c){return r.log(ee(c)),r.fail("Could not reach GitHub to create the repository.",{action:"git.createGithubRepository"}),!1}if(!i.ok){let c=await i.json();return r.log(c.errors?.[0]?.message||c.message||`GitHub answered ${i.status}.`),r.fail("Could not create the GitHub repository.",{action:"git.createGithubRepository"}),!1}let a=await i.json();r.log(`Created ${a.html_url}`);let s=p();r.step(k[1]);try{await s.gitAddRemote("origin",a.clone_url)}catch(c){return r.log(ee(c)),r.fail("The repository was created, but the remote could not be added.",{action:"view.setWorkspace",actionArgs:{workspace:"publish"}}),!1}r.step(k[2]);try{await s.gitPush({setUpstream:!0})}catch(c){return r.log(ee(c)),r.fail("The repository was created, but the push failed.",{action:"git.push"}),!1}let{refreshGitStatus:d}=await (le("1phx90zk"),import("./source-control-1phx90zk.js"));return await d(),r.done(a.html_url),C.success(`Repository created: ${a.html_url}`,{key:"github.repo"}),!0}var w=[];function kt(){return _e()&&Q(p().listProjects)}async function aS(){if(!kt()){w=[];return}try{w=await p().listProjects?.()??[]}catch{w=[]}}function VD(){return w}function X(t){w=t}var K=2,Rt=1e4;class Z extends Error{blockedBy;constructor(t,e){super(t.length===0?`Studio did not report ${K} consecutive quiet frames within ${e}ms`:`Studio was not idle after ${e}ms — blocked by ${t.join("; ")}`);this.name="NotIdleError",this.blockedBy=t}}function Y(){return[{blockers:()=>{let t=ZO();return t>0?[`render: ${t} renderer(s) mid-paint`]:[]},name:"render"},{blockers:pL,name:"canvas"},{blockers:()=>{let t=aI();if(t.length===0)return[];return[`platform: ${t.length} in-flight (${[...new Set(t)].join(", ")})`]},name:"platform"},{blockers:g$,name:"overlay"},{blockers:sN,name:"activity"},{blockers:GD,name:"grid"}]}function At(t=Y()){let e=[];for(let o of t)e.push(...o.blockers());return e}function et(t={}){let{frames:e=K,now:o=()=>Date.now(),raf:r=(s)=>{requestAnimationFrame(()=>s())},sources:i=Y(),timeoutMs:a=Rt}=t;return new Promise((s,d)=>{let c=o()+a,l=0,f=!1,J=[],H=()=>{if(f)return;let P=At(i);if(P.length>0)J=P,l=0;else if(l+=1,l>=e){f=!0,s();return}if(o()>=c){f=!0,d(new Z(P.length>0?P:J,a));return}r(H)};r(H)})}var ot=/\.toggle[A-Z]/;function $t(t){return t.replace(/\.toggle([A-Z])/,(e,o)=>`.set${o}`)}function rt(t){return!ot.test(t.id)}var Dt={"file.contextMenu":{disposition:"refused",note:"opening a menu to press an item names a control; the ITEM is the command"},"layers.contextMenu":{disposition:"refused",note:"matched RENDERED TEXT, which R1 of scripts/screenshots/README.md forbids; a row is addressed by its data-jx-path"},"project.showWelcome":{disposition:"refused",note:"cold start is a startup profile (?profile=fresh), not an action"},"settings.setSection":{disposition:"refused",note:`mirrored the section registry's LABELS; say settings.open { section: "contexts" }`},"view.setStatus":{disposition:"refused",note:"the status bar is not staged — if a capture needs a calm shell, the app must BE calm"}},Et=new Map(Object.entries(Dt)),Tt={openSettings:'a user opens Settings — run("settings.open")',select:'a user selects a node — run("selection.set", { path })',setActivity:'a user picks a Navigator panel — run("navigator.showPanel", { panel })',setRightTab:'a user picks an Inspector tab — run("inspector.setTab", { tab })',setStatus:"the status bar reports what the app just did; staging it is the one lie the Remote Rule (studio.md §13.5) names outright",setZoom:'a user zooms — run("canvas.setZoom", { zoom })'},Gt=new Map(Object.entries(Tt));function I(t,e){let o=t[e];if(o===void 0)return[];if(!Array.isArray(o))throw TypeError(`seed argument "${e}" must be an array`);return o}function It(t,e){let o=t[e];if(!_(o))throw TypeError(`seed argument "${e}" must be an object`);return o}function Ut(t,e){let o=t[e];if(o===void 0)return;if(!n(o))throw TypeError(`seed argument "${e}" must be a string`);return o}function Lt(t){return[{boundary:"the assistant's model stream",id:"seed.assistant",run:(e)=>{t.seedAssistantMessages(I(e,"messages"))}},{boundary:"the collaboration websocket (awareness + sync)",id:"seed.collab",run:(e)=>{let o=h.value;if(!o)return;let r=Tn(o);r.status="synced",r.active=!0;let i=[];for(let a of I(e,"peers")){let s={...a.state};s.focusedPath??=o.documentPath,i.push({...a,state:s})}r.peers=i,sr()}},{boundary:"the Cloudflare Pages API",id:"seed.publish",run:(e)=>{let o=Ut(e,"accountId"),r={deployment:It(e,"deployment")};if(o)r.accountId=o;t.seedPublishConnected(r)}},{boundary:"the platform's git routes (`gitStatus` / `gitBranches` / `gitLog`)",id:"seed.git",run:(e)=>{let{status:o,branches:r,log:i}=e;u.git.status=o??null,u.git.branches=r??null,u.git.logEntries=i??null,u.git.loading=!1,u.git.error=null,sr()}},{boundary:"the platform's recent-projects store (desktop IPC / cloud API)",id:"seed.projectList",run:(e)=>{X(I(e,"projects")),sr()}}]}class U extends Error{id;constructor(t,e){super(`automation refuses "${t}" — ${e}`);this.name="AutomationRefusedError",this.id=t}}function Mt(t){let e=[];for(let o of t.visible()){if(!rt(o))continue;let r=t.disabledReason(o.id),i={enabled:r===void 0,id:o.id,title:o.title};if(o.args)i.args=o.args;if(r!==void 0)i.requires=r;e.push(i)}return e}function Ft(t,e,o){if(o.has(t))return`"${t}" is a seed, not a command — call seed("${t}", …)`;let r=Et.get(t);if(r)return`"${t}" is refused by spec §13.5: ${r.note}`;let i=e.list().filter((a)=>rt(a)).map((a)=>a.id);return`unknown command "${t}" — the registry declares ${i.length} scriptable id(s)`}function _t(t){let e=new Map(Lt(t).map((r)=>[r.id,r])),o=new Set(e.keys());return{probe:{commands:()=>Mt(t.registry),idle:(r={})=>et(r),pointAt:(r)=>mL(r.path),revealPath:(r)=>Ab(r),seeds:()=>[...e.values()].map((r)=>({boundary:r.boundary,id:r.id})),state:()=>t.registry.context()},async run(r,i={}){if(ot.test(r))throw new U(r,`it names a delta against state the caller cannot observe; call "${$t(r)}"`);let{registry:a}=t;if(!a.get(r))throw Error(Ft(r,a,o));await a.run(r,i)},async seed(r,i={}){let a=r.startsWith("seed.")?r.slice(5):r,s=Gt.get(a);if(s)throw new U(r,`a seed stands in for a remote, never for a user: ${s}`);let d=e.get(r.startsWith("seed.")?r:`seed.${r}`);if(!d)throw Error(`unknown seed "${r}" — declared seeds are ${[...e.keys()].join(", ")}`);await d.run(i)}}}function yw(t){return new URLSearchParams(t).get("automation")==="1"}function UD(t){if(!yw(location.search))return!1;return globalThis.__jxAutomation=_t(t),!0}var nt={$schema:"https://jxsuite.com/schema/v1",$id:"StudioJxsuiteUpdate",$description:"The on-open offer to bring a project's `@jxsuite/*` dependencies up to their newest published versions: one sentence, and the packages that would move. A `jx-dialog`, so the platform owns modality, Escape, focus restoration and the backdrop, and the kit draws both answers. Nothing here asks the registry or writes a manifest: `packages/jxsuite-update.ts` keeps the lookup, the dismissal key and the install, and this document only says what is on offer.",tagName:"jx-dialog",$props:{headline:"Update @jxsuite packages?",confirmLabel:"Update",cancelLabel:"Not now",size:"sm"},attributes:{part:"jxsuite-update"},onconfirm:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/confirm"},value:[]}]},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/cancel"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},style:{$description:'The old body was a lit template with no stylesheet at all, which is why the conversion is mostly a deletion. Two `<br />`s stood in for a paragraph break, and one `<span style="white-space: pre-line">` held every package as a single `\\n`-joined string — a list spelled as whitespace. Neither is addressable and neither announces as what it is, so a screen reader read one run-on line and a test could only match a substring of it. It is a `<ul>` of keyed rows now: the list says how many packages there are, and each row is `[data-package]`. The one token repair travels with it — that span asked for `--spectrum-font-size-75`, which resolves only inside `<sp-theme>`, and a document mounted in the dialog layer is outside it, so the size silently fell back to the hard-coded `12px` written beside it.','& [part="offer"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)"},'& [part="lede"]':{margin:"0"},'& [part="list"]':{$description:"Capped and scrolling, because the count is the registry's rather than this dialog's: a project that has not been opened in a year can have every `@jxsuite/*` package behind at once, and a dialog that grows past the viewport puts its own Update button off screen.",listStyle:"none",margin:"0",padding:"0",display:"flex",flexDirection:"column",gap:"var(--jx-space-1)",maxHeight:"240px",overflowY:"auto"},'& [part="package"]':{display:"flex",justifyContent:"space-between",alignItems:"baseline",gap:"var(--jx-space-3)",fontSize:"var(--jx-text-sm)"},'& [part="package-name"]':{color:"var(--fg)"},'& [part="package-move"]':{$description:"Tabular figures, so a column of versions does not jitter between rows of different widths.",color:"var(--fg-dim)",fontVariantNumeric:"tabular-nums",whiteSpace:"nowrap"}},children:[{tagName:"div",attributes:{part:"offer"},children:[{tagName:"p",attributes:{part:"lede"},textContent:"Newer versions of these packages have been published. Update the project to them?"},{tagName:"ul",attributes:{part:"list"},children:[{$prototype:"Array",items:{$ref:"#/state/packages"},key:{$ref:"$map/item/name"},map:{tagName:"li",attributes:{part:"package","data-package":"${$map.item.name}"},children:[{tagName:"span",attributes:{part:"package-name"},textContent:"${$map.item.name}"},{tagName:"span",attributes:{part:"package-move"},textContent:"${$map.item.current} → ${$map.item.target}"}]}}]}]}]};T("jxsuite-update",nt);function it(t){let e=document.createElement("div");e.style.pointerEvents="auto",e.setAttribute(Ue,ft("dialog","jxsuite-update")),t.layer.append(e);let o=!1,r=()=>{if(o)return;o=!0,t.onClosed()},i=()=>o,a=g({cancel:()=>{t.onCancel()},closed:r,confirm:()=>{t.onConfirm()},packages:t.packages}),s=null,d=R("jxsuite-update",a,e).then(async(c)=>{s=c;let l=c.root;if(i())return c.dispose(),l;if(await Yt(l),i())return l;return Ot(l),l});return{close(){let c=s?.root;if(c instanceof HTMLElement)Nt(c);s?.dispose(),s=null,e.remove(),r()},host:e,ready:d}}function ww(t){return t.replace(/^[\^~>=<v\s]+/,"").trim().split(/\s+/)[0]??""}function at(t){if(t.includes(":"))return!1;return/^\d+\.\d+/.test(ww(t))}function st(t){let e=ww(t).split(/[-+]/)[0]??"",[o=0,r=0,i=0]=e.split(".").map((a)=>Math.trunc(Number(a))||0);return[o,r,i]}function Ht(t,e){let o=st(t),r=st(e);for(let i=0;i<3;i++){let a=o[i]??0,s=r[i]??0;if(a!==s)return a<s?-1:1}return 0}function lS(t,e){if(!at(t)||!at(e))return!1;return Ht(e,t)>0}var L="@jxsuite/";async function M(){let t=p();if(!t.packageVersions)return[];let e;try{e=await t.packageVersions()}catch{return[]}let o=[];for(let r of e)if(r.name.startsWith(L)&&lS(r.current,r.latest))o.push({current:r.current,dev:Boolean(r.dev),latest:r.latest,name:r.name});return o}function ct(t,e){let o=e.map((r)=>`${r.name}@${r.latest}`).toSorted().join(",");return`jx:jxsuite-update-dismissed:${t}:${o}`}function Bt(t,e){try{return localStorage.getItem(ct(t,e))==="1"}catch{return!1}}function Vt(t,e){try{localStorage.setItem(ct(t,e),"1")}catch{}}async function N(t){let e=p();if(!e.setPackageVersions||t.length===0)return;let o=el({status:"Updating @jxsuite packages…",title:"Updating dependencies"});try{let r=await e.setPackageVersions(t.map((i)=>({dev:i.dev,name:i.name,version:`^${i.latest}`})));if(r.ok)o.done(),C.success(`Updated ${t.length} @jxsuite package(s) to their latest versions.`);else o.fail(r.log??"Update failed")}catch(r){o.fail(r instanceof Error?r.message:String(r))}}function Wt(t){return new Promise((e)=>{let o=!1,r=(d)=>{if(o)return;o=!0,e(d)},i=!1,a=()=>{if(i)return;i=!0,s.close()},s=it({layer:tt("dialog"),onCancel:()=>{a()},onClosed:()=>{r(!1),a()},onConfirm:()=>{r(!0),a()},packages:t.map((d)=>({current:d.current,name:d.name,target:`^${d.latest}`}))})})}async function mm(t){if(yw(location.search))return;if(!p().setPackageVersions)return;let o=await M();if(o.length===0||Bt(t,o))return;if(!await Wt(o)){Vt(t,o);return}await N(o)}var j=["package.json","bun.lock","bun.lockb"],qt=new Set(["??","U"]),zt=25;function A(t){if(Array.isArray(t))return t.map((e)=>A(e));if(v(t)){let e={};for(let[o,r]of Object.entries(t).toSorted(([i],[a])=>i<a?-1:1))e[o]=A(r);return e}return t}function lt(t){let e={...t};for(let o of["dependencies","devDependencies"]){let r=e[o];if(!v(r))continue;let i={...r};for(let a of Object.keys(i))if(a.startsWith(L))i[a]="*";e[o]=i}return e}function Xt(t,e){if(t===null||e===null)return!1;let o,r;try{o=JSON.parse(t),r=JSON.parse(e)}catch{return!1}if(!v(o)||!v(r))return!1;return JSON.stringify(A(lt(o)))===JSON.stringify(A(lt(r)))}async function D(t,e){try{return await p().gitShow({path:t,ref:e})}catch{return null}}async function pt(t){try{return await p().readFile(t)}catch{return null}}async function dt(t){let e=[],o=[],r=!0;for(let i of j){let a=t.files.filter((c)=>c.path===i);if(a.length===0)continue;let s=await D(i,"@{u}");if(a.every((c)=>qt.has(c.status))){if(s!==null)o.push(i);continue}let d=await D(i,"HEAD");if(s===null||s===d)continue;if(e.push(i),i==="package.json")r&&=Xt(d,await pt(i))}return{automated:r,discard:e,removeUntracked:o}}function mt(t){return t.discard.length===0&&t.removeUntracked.length===0}async function Kt(t){let e=[...new Set(t.files.filter((o)=>!j.includes(o.path)).map((o)=>o.path))];if(e.length>zt)return!0;for(let o of e){let r=await D(o,"@{u}");if(r!==null&&r!==await D(o,"HEAD"))return!0}return!1}async function Zt(t){let e=p();if(t.discard.length>0)await e.gitUnstage(t.discard),await e.gitDiscard(t.discard);for(let o of t.removeUntracked)await e.deleteFile(o)}async function O(){let t=p(),e=[];try{e=await M()}catch{e=[]}if(e.length>0&&t.setPackageVersions){await N(e);return}if(!t.installDependencies)return;let o=el({status:"Installing dependencies…",title:"Syncing dependencies"});try{let r=await t.installDependencies();if(r.ok)o.done();else o.fail(r.log??"Install failed")}catch(r){o.fail(ee(r))}}async function gt(t){let e=p();try{await Zt(t)}catch(o){throw Error(`Could not reset local package files: ${ee(o)}`,{cause:o})}try{await e.gitPull()}catch(o){throw await O(),o}C.warn("Local package updates were superseded by pulled changes.",{source:"Source Control"}),await O()}async function Qt(t){let e=p(),o;try{o=await e.gitStatus()}catch{throw t}if(!(o.behind>0))throw t;let r=await dt(o);if(mt(r)||await Kt(o))throw t;if(!r.automated){if(!await qo("Discard local package changes?","package.json / bun.lock have local edits that conflict with incoming changes. Discard them, pull, and re-sync packages?",{confirmLabel:"Discard and pull",destructive:!0}))throw t}await gt(r)}async function ut(){let t;try{let e=await p().listDirectory("");t=new Set(e.filter((o)=>o.type==="file").map((o)=>o.name))}catch{t=new Set(j)}return Promise.all(j.map((e)=>t.has(e)?pt(e):Promise.resolve(null)))}async function F(){let t=p(),e=await ut(),o=null;try{await t.gitFetch(),o=await t.gitStatus()}catch{o=null}if(o&&o.behind>0){let i=await dt(o);if(!mt(i)&&i.automated){await gt(i);return}}try{await t.gitPull()}catch(i){await Qt(i);return}let r=await ut();if(e.some((i,a)=>i!==r[a]))await O()}async function gm(){let t=p();try{let e=await t.gitStatus();if(!e.isRepo||!Array.isArray(e.remotes)||e.remotes.length===0)return}catch{return}C.info("Syncing project…",{key:"project.sync",source:"Source Control"});try{await F()}catch(e){C.warn("The project could not be synced with its remote.",{detail:ee(e),key:"project.sync",source:"Source Control",tier:"problem"})}}async function te(){let t=p(),{git:e}=u,o;try{o=await t.gitStatus()}catch(r){e.error=ee(r);return}if(e.status=o,!o.isRepo){e.branches=null;return}try{e.branches=await t.gitBranches()}catch(r){e.error=ee(r)}}async function ks(){if(!S)return;let{git:t}=u;t.loading=!0,t.error=null;try{if(await te(),t.lastUpdated=ar(),t.rev+=1,await oe(),t.logEntries!==null)await cS()}catch(e){t.error=ee(e)}finally{t.loading=!1}}async function oe(){let t=u.git.diffState;if(!t)return;let e=u.git.status?.files.find((o)=>o.path===t.filePath);if(!e||!ht(e.status)){u.git.diffState=null;return}try{u.git.diffState=await G(t.filePath,e.status)}catch{}}async function rT(t){if(u.git.rev+=1,!u.git.loading)ks();let e=u.git.diffState;if(!t||e?.filePath!==t)return;try{u.git.diffState=await G(t,e.fileStatus)}catch{}}async function cS(){try{u.git.logEntries=await p().gitLog(30)}catch(t){u.git.error=ee(t)}}async function dS(t){let e=p();if(!e.gitClone){C.warn("Cloning is not supported on this platform.",{source:"Source Control"});return}let o=await Qn("Clone Git Repository",{confirmLabel:"Clone",message:"Repository URL",placeholder:"https://github.com/user/repo.git",validate:(r)=>r.trim()?"":"Enter a repository URL."});if(!o)return;try{C.info("Cloning repository…",{key:"git.clone",source:"Source Control"});let r=await e.gitClone(o);if(r.root)C.success("Clone complete.",{key:"git.clone"}),await t.openRecentProject(r.root)}catch(r){C.error("Could not clone the repository.",{detail:ee(r),key:"git.clone",source:"Source Control"})}}function vb(){return _e()&&Boolean(p().gitClone)}function Vs(){return _e()&&p().gitHosted===!0}function sT(){return _e()&&Q(p().createPullRequest)}var re=new Map([["A","added"],["D","deleted"],["M","modified"],["R","renamed"],["U","untracked"]]);function ne(t){return re.get(t)??"changed"}var ie=new Map([["A","NEW"],["D","DELETED"],["M","EDIT"],["R","RENAMED"],["U","NEW"]]);function aT(t){return ie.get(t)??"EDIT"}var ae=new Set(["M","A","U","D"]);function ht(t){return ae.has(t)}async function G(t,e){let o=p(),r=e!=="A"&&e!=="U",i=e!=="D",[a,s]=await Promise.all([r?o.gitShow({path:t,ref:"HEAD"}):Promise.resolve(""),i?o.readFile(t):Promise.resolve("")]);return{currentContent:s,filePath:t,fileStatus:e,originalContent:a}}async function lT(t,e){try{return await G(t,e)}catch(o){return console.warn("loadDiffForLens:",ee(o)),null}}var E={};function cT(t){E=t}function dT(){E.cloneRepository?.()}function yt(t){return u.git.status?.files.find((e)=>e.path===t)}async function uT(t){let e=yt(t);if(!e)return;let o=ht(e.status)?B(e.path,e.status):`"${e.path}" has no change this view can open.`;if(o){u.git.error=o;return}try{u.git.loading=!0;let r=await G(e.path,e.status);u.git.diffState=r,E.setGitDiffState?.(r);let i=await V(e.path);if(i)E.setCanvasMode?.(i,"git-diff")}catch(r){u.git.error=`Failed to load diff: ${ee(r)}`}finally{u.git.loading=!1}}async function y(t){let e=p();u.git.loading=!0,u.git.error=null;try{return await t(e),await ks(),!0}catch(o){return u.git.error=ee(o),u.git.loading=!1,!1}}async function se(){try{C.info("Initializing repository…",{key:"git.init"}),await p().gitInit(),C.success("Repository initialized.",{key:"git.init"})}catch(t){C.error("Could not initialize the repository.",{action:"git.init",detail:ee(t),key:"git.init",source:"Source Control"});return}await ks()}async function ce(){await y((t)=>t.gitPush())}async function hT(){await y((t)=>t.gitFetch())}async function pT(){u.git.loading=!0,u.git.error=null;try{await F(),await ks()}catch(t){u.git.error=ee(t),u.git.loading=!1}}async function ue(){await z({projectName:S?.name||"my-project"})}async function pe(){if(await hS())C.success("Signed in to GitHub.",{key:"github.auth"})}async function fT(t,e){await y((o)=>e?o.gitStage([t]):o.gitUnstage([t]))}async function mT(t){let e=(u.git.status?.files??[]).filter((o)=>Boolean(o.staged)!==t).map((o)=>o.path);if(e.length===0)return;await y((o)=>t?o.gitStage(e):o.gitUnstage(e))}var b={paths:new Set,root:""};function de(){let t=S?.projectRoot??"";if(b.root!==t)b={paths:new Set,root:t};let e=u.git.status?.files??[],o=new Set(e.map((i)=>i.path));for(let i of b.paths)if(!o.has(i))b.paths.delete(i);let r=e.filter((i)=>!b.paths.has(i.path));for(let i of r)b.paths.add(i.path);return r.filter((i)=>!i.staged).map((i)=>i.path)}async function gT(){if(u.git.loading||!u.git.status?.isRepo)return;let t=de();if(t.length>0)await y((e)=>e.gitStage(t))}async function bT(t){if(yt(t)?.status==="U")return;if(!await qo("Discard Changes",`Discard changes to ${t}?`,{confirmLabel:"Discard",destructive:!0}))return;await y((o)=>o.gitDiscard([t]))}async function vT(){let{branches:t,status:e}=u.git,o=await Qn("New Branch",{confirmLabel:"Create",message:`Branching from ${t?.current||e?.branch||"the current branch"}.`,placeholder:"feature/my-change",validate:(r)=>r.trim()?"":"Enter a branch name."});if(o)await y((r)=>r.gitCreateBranch(o.trim()))}async function yT(t){if(t===u.git.branches?.current)return;if(Vs()){if(!await qo("Switch Branch",`Each branch opens in its own session, so switching to ${t} reloads Studio on that branch.`,{confirmLabel:"Switch and reload"}))return}await y((e)=>e.gitCheckout(t))}function uS(t){let e=t.path.split("/"),o=e.pop()??t.path,r=e.join("/"),i=ne(t.status);return{cannotDiscard:t.status==="U",dir:r,hasDir:r!=="",included:Boolean(t.staged),key:t.path,label:`${t.path}, ${i}`,name:o,path:t.path,status:t.status,statusWord:i}}var bt=[["components","Components"],["layouts","Layouts"],["styles","Styles"]];function me(t){let e=Vl(t);if(e!==null)return e;let[o]=t.split("/");if(o==="pages")return ui;if(bt.some(([r])=>r===o))return`folder:${o}`;return Ys.has(nn(t))?"media":"other"}function wT(t){let e=[...wm().map((r)=>[r.key,r.title]),...bt.map(([r,i])=>[`folder:${r}`,i]),["media","Media"],["other","Other"]],o=new Map;for(let r of t){let i=me(r.path);o.set(i,[...o.get(i)??[],r])}return e.flatMap(([r,i])=>{let a=o.get(r);return a?[{files:a.map((s)=>uS(s)),key:r,name:i}]:[]})}function xT(t){return{hash:t.hash.slice(0,7),key:t.hash,message:t.message,meta:`${t.author} · ${xw(t.date)}`}}function xw(t){let e=new Date(t),o=ar()-e.getTime(),r=Math.floor(o/60000);if(r<1)return"just now";if(r<60)return`${r}m ago`;let i=Math.floor(r/60);if(i<24)return`${i}h ago`;let a=Math.floor(i/24);if(a<30)return`${a}d ago`;return e.toLocaleDateString()}function _T(t){return t?`Last updated ${new Date(t).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"})}`:""}var x=null;function ST(){if(x)return;x=setInterval(()=>{if(u.workspace==="publish"&&!u.git.loading)ks()},KO)}function yb(){if(x)clearInterval(x),x=null;b={paths:new Set,root:""}}function fe(){return[{category:"Source Control",id:"git.init",level:"project",menus:["commandbar/overflow","palette"],group:"7_scm",requires:"an open project that git is not already tracking",when:(t)=>t.project.open,enablement:(t)=>!t.project.isRepo,run:async()=>{await se()},title:"Initialize Repository"},{category:"Source Control",id:"git.createGithubRepository",level:"project",menus:["commandbar/overflow","palette"],group:"7_scm",requires:"a project tracked by git",when:(t)=>t.project.open,enablement:(t)=>t.project.isRepo,run:async()=>{await ue()},title:"Create GitHub Repository"},{category:"Source Control",id:"git.push",level:"project",menus:["commandbar/overflow","palette"],group:"7_scm",requires:"a project tracked by git",when:(t)=>t.project.open,enablement:(t)=>t.project.isRepo,run:async()=>{await ce()},title:"Push"},{category:"Source Control",id:"git.signInToGithub",level:"application",menus:["palette"],group:"7_scm",run:async()=>{await pe()},title:"Sign In to GitHub"}]}function CT(t){t.registerAll(fe())}
|
|
2
|
-
export{aS,VD,yw,UD,ww,lS,mm,gm,bb,ks,rT,cS,dS,vb,Vs,sT,aT,lT,cT,dT,uT,hT,pT,fT,mT,gT,bT,vT,yT,uS,wT,xT,xw,_T,ST,yb,CT};
|
|
3
|
-
|
|
4
|
-
//# debugId=2B7EE9DB9B9BE2F964756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-vxjap704.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{p,_e}from"./studio-w67vfgy5.js";import{C}from"./studio-ahf3cspq.js";function v(e){return e.trim().replace(/\/+$/,"")}function u(e){return e.trim()}var pt={aiBaseUrl:{default:"",key:"jx.ai.baseUrl",normalize:v,scope:"user"},aiOpenAiKey:{default:"",key:"jx.ai.openaiKey",normalize:u,scope:"user",secret:!0},aiModel:{default:"gpt-4o",key:"jx.ai.model",normalize:u,scope:"user"},keybindings:{default:"",key:"jx.keybindings",normalize:(e)=>e.trim()==="{}"?"":e.trim(),scope:"user"},theme:{default:"",key:"jx-studio-theme",normalize:u,scope:"user"},showIgnoredFiles:{default:"",key:"jx.files.showIgnored",normalize:u,scope:"user"},developerPanels:{default:"",key:"jx.panels.developer",normalize:u,scope:"user"},cfAccountId:{default:"",key:"jx.cf.accountId",normalize:u,scope:"user"},cfToken:{default:"",key:"jx.cf.token",normalize:u,scope:"user",secret:!0}},S=Object.values(pt),f=S.filter((e)=>e.scope==="user"),P=f.map((e)=>e.key);function h(e){let t=e.schedule??queueMicrotask,n=null,i=Promise.resolve(),r=Promise.resolve();function s(){let o=n;if(n=null,!o)return i;return i=i.then(()=>e.send(o)).catch((a)=>{e.onError?.(a,o)}),i}return{enqueue(o){if(n){Object.assign(n,o);return}n={...o},r=new Promise((a)=>{t(()=>{s().then(a)})})},settled(){return r}}}var c=new Map;function m(){return typeof localStorage>"u"?void 0:localStorage}function k(e,t){try{if(t===null)m()?.removeItem(e);else m()?.setItem(e,t)}catch{}}try{for(let e of S){let t=m()?.getItem(e.key);if(t!==null&&t!==void 0)c.set(e.key,t)}}catch{}function Uo(e){return c.get(e.key)??""}function RA(e){return(c.get(e.key)??"")!==""}var y=new Set;function Np(e){return y.add(e),()=>{y.delete(e)}}function l(e){for(let t of y)t(e)}var g=h({onError(e){C("error","Your settings could not be saved.",{detail:e instanceof Error?e.message:String(e),key:"settings-write",source:"Settings"})},async send(e){if(!_e())return;let t=p();if(!t.patchSettings)return;let n={},i=[];for(let[r,s]of Object.entries(e))if(s)n[r]=s;else i.push(r);await t.patchSettings({remove:i,set:n})}});function DA(){return g.settled()}function d(e){let t=[];for(let[n,i]of Object.entries(e)){if((c.get(n)??null)===i)continue;if(i===null)c.delete(n);else c.set(n,i);k(n,i),t.push(n)}return t}function fx(e,t){return e.normalize?e.normalize(t):t}function xr(e,t){let n=fx(e,t),i=d({[e.key]:n});if(i.length>0)g.enqueue({[e.key]:n}),l(i)}function NA(e){let t={};for(let[i,r]of e)t[i.key]=fx(i,r);let n=d(t);if(n.length>0)g.enqueue(t),l(n)}function Ap(e){let t={};for(let i of e)t[i.key]=null;let n=d(t);if(n.length>0)g.enqueue(t),l(n)}async function AA(){if(!_e())return;let e=p();if(!e.getSettings)return;let t;try{t=await e.getSettings()}catch{return}let n={},i=!1;for(let s of f){let o=t[s.key];if(o)n[s.key]=o;else if(c.get(s.key))i=!0}let r=d(n);if(r.length>0)l(r);if(i){let s={};for(let o of f){let a=c.get(o.key);if(a&&!t[o.key])s[o.key]=a}g.enqueue(s)}}function x(e){let t={};for(let i of f)t[i.key]=e[i.key]??null;let n=d(t);if(n.length>0)l(n)}function OA(){if(!_e())return;p().subscribeSettings?.(x)}
|
|
2
|
-
export{pt,Uo,RA,Np,DA,fx,xr,NA,Ap,AA,OA};
|
|
3
|
-
|
|
4
|
-
//# debugId=344EF29CEB15DC3764756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-xebavr9s.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{de,C}from"./studio-ahf3cspq.js";import{Q,_}from"./studio-zsjpsw08.js";var st={functionEditor:null,blockActionBarEl:null,selDragCleanup:null,dndCleanups:[],elementsCollapsed:new Set,elementsFilter:"",_currentDropTargetRow:null,layerDragSourceHeight:0,_completionRegistered:!1,_layersCollapsed:null};var m=0;function VO(){return m+=1,m}var l=new Map;function bo(e){let r=l.get(e);if(!r)r=v(e),l.set(e,r);return r}function v(e){return{centerObserver:null,monacoDiffEditor:null,monacoEditor:null,needsCenter:!0,panX:0,panY:0,panels:[],paneId:e,panzoomWrap:null,stage:null,prevCanvasMode:null,prevStylebookCustomizedOnly:null,prevStylebookFilter:null,renderGeneration:0,sourceCollabCleanup:null,stageScrollbar:null,wrap:null}}function wh(e){return e.wrap}function Gp(){return[...l.values()]}function Xc(e){if(!e)return null;for(let r of l.values())if(wh(r)?.contains(e))return r;return null}function g(e){for(let r of e.panels)r.renderScope?.stop(),r.renderScope=null;e.panels.length=0,e.prevCanvasMode=null}function UO(e,r){let t=bo(e);return t.wrap=r,g(t),t}function qO(e){if(l.get(e))G$(e);let t=v(e);return l.set(e,t),t}var S=null;function GO(e){S=e}function G$(e){let r=l.get(e);if(!r)return;S?.(r),g(r),y(e)}function y(e){l.delete(e)}var Kp="commit";function b(e){return _(e)&&Q(e.then)}function gv(e){let r=new Map,t=new Map,o=new Map,a=!1,u=!1,c=!1;function f(n,i){if(!b(i))return i;let s=i.finally(()=>{if(o.get(n)===s)o.delete(n)});return o.set(n,s),s}let d={arm(n,i,s){clearTimeout(r.get(n)),t.set(n,s),r.set(n,setTimeout(()=>{r.delete(n),t.delete(n),f(n,s())},i))},cancel(){for(let n of r.values())clearTimeout(n);r.clear(),t.clear()},flush(n){let i=t.get(n);if(!i)return o.get(n);return clearTimeout(r.get(n)),r.delete(n),t.delete(n),f(n,i())},ahead:()=>a,markAhead(){a=!0},typed:()=>u,markTyped(){a=!0,u=!0},markSettled(){a=!1,u=!1},shared:()=>c,markShared(){c=!0}};return e._writes=d,d}var T={logic:{holds:"The handler you were typing",reached:"written into",source:"Logic"},source:{holds:"The source you were typing",reached:"parsed into",source:"Editor"}};function p(e,r,t){if(e._writes?.typed()!==!0)return!0;let a=e._editingTab??null,u=a?.documentPath??"Untitled",{holds:c,reached:f,source:d}=T[r],n=t?{detail:h(t.error)}:{};if(n.key=`buffer-discarded:${r}:${a?.id??"none"}`,n.source=d,a?.documentPath)n.path=a.documentPath;return C.warn(`${c} was discarded — it was never ${f} "${u}".`,n),!1}function h(e){return e instanceof Error?e.stack??e.message:String(e)}function bv(e,r){let t=e?._writes;if(!e||!t)return!0;let o;try{o=t.flush(Kp)}catch(a){return t.cancel(),p(e,r,{error:a})}if(t.cancel(),b(o))return o.then(()=>p(e,r,null),(a)=>p(e,r,{error:a})),!0;return p(e,r,null)}function K$(e){e?._writes?.cancel()}function Yd(e){return Boolean(e?.getModel())}function Jp(e,r){if(!Yd(e)||e.hasTextFocus()||e._writes?.ahead()||e._writes?.shared())return!0;return r!==void 0&&e.getValue()!==r}function w(e){let r=de(e);return[...Gp().map((o)=>o.monacoEditor),st.functionEditor].filter((o)=>o!=null&&o._editingTab!=null&&de(o._editingTab)===r&&Yd(o))}async function Zd(e){for(let r of w(e)){if(!Yd(r))continue;try{await r._writes?.flush(Kp)}catch(t){let o={detail:h(t),key:`buffer-commit:${e.id}`,source:"Editor"};if(e.documentPath)o.path=e.documentPath;C.error(`Could not save the editor's contents into "${e.documentPath??"Untitled"}".`,o)}}}function Yp(e){return w(e).some((r)=>r._writes?.typed()===!0)}
|
|
2
|
-
export{st,VO,bo,wh,Gp,Xc,UO,qO,GO,G$,Kp,gv,bv,K$,Yd,Jp,Zd,Yp};
|
|
3
|
-
|
|
4
|
-
//# debugId=1981365515F0F7E564756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-yg5n49za.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{Ot,Nt,ae}from"./studio-f2j9et3h.js";import{p}from"./studio-w67vfgy5.js";import{ds}from"./studio-8x8616xd.js";import{g}from"./studio-ahf3cspq.js";import{Ue,ft,T,R,Yt,tt}from"./studio-cvz0e00f.js";import{zl,cN,Cb,qT,dN,Ri,Ad}from"./studio-zxm98z2m.js";import{db,DE}from"./studio-h7gy12h2.js";import{S}from"./studio-rt498t2v.js";import{Q}from"./studio-zsjpsw08.js";import{le}from"./studio-0g2sm01j.js";function Rl(e){let t=e.trim().replaceAll("\\","/").split("/").filter((n)=>n!=="");return t.some((n)=>n==="."||n==="..")?null:t.join("/")}var C={$schema:"https://jxsuite.com/schema/v1",$id:"StudioPublish",$description:"Publish: the one-click Cloudflare Pages flow, as a `jx-dialog` over the kit. Eight bodies, one at a time, because the reader is at exactly one point of a chain — a host that cannot reach Cloudflare at all, a question still in flight, a connection that lapsed, an invitation to connect, a stored token Cloudflare refused, a field to paste a replacement into, the create-and-connect form, and the connected status. `publish/publish-panel.ts` keeps every one of those decisions and the calls that settle them; this document knows only which of the eight it was told to draw. **The token is never painted.** The field below binds no `value` — it is written by the reader and read once, on its way to storage — so a stored secret cannot reach the attribute, the serialised HTML or the accessibility tree, which is `studio.md` §15 rule 1 written as a missing binding rather than as a rule somebody remembers.",tagName:"jx-dialog",$props:{headline:"Publish",confirmLabel:"",cancelLabel:"Close",size:"md"},attributes:{part:"publish"},oncancel:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},onclose:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/closed"},value:[]}]},style:{$description:"What the five `.publish-*` names carried, keyed on `part`, and most of them do not survive the move. `.publish-modal` and its `.new-project-modal` base were a fixed card, a scroll body, a border, a shadow and a `z-index: 1000` — a modal `<dialog>` is every one of those, and the top layer is what the z-index was climbing towards. `.publish-field` was a label stacked over a control, which is `jx-field`'s whole shape. What is left is the column gap between bodies, the two button rows, the hint and the refusal. Nothing here uses `--spectrum-*`: those custom properties resolve only inside `<sp-theme>`, and a document mounted in a layer host is outside it, so each would silently have taken its hard-coded fallback.",'& [part="body"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)"},'& [part="note"], & [part="status-line"], & [part="deployment"]':{margin:"0",lineHeight:"1.5"},'& [part="rows"]':{display:"flex",flexDirection:"column",gap:"var(--jx-space-3)"},'& [part="actions"]':{$description:'Wraps rather than overflows (studio-ui-guidelines.md §4.6): two buttons whose labels are whole phrases — "Verify & Connect", "Preferences › Accounts" — are wider than a narrow dialog at the sizes a reader may have set.',display:"flex",flexWrap:"wrap",gap:"var(--jx-space-2)"},'& [part="submit"]':{alignSelf:"flex-start"},'& [part="hint"]':{$description:"Publishing rides every commit, so the connected body's only job is to say what is already happening. Dim, because it is a standing fact rather than something to act on.",margin:"0",color:"var(--fg-dim)",fontSize:"var(--jx-text-sm)"},'& [part="failure"]':{$description:'`failure` and not `error`: `jx-textfield` and `jx-select` each draw a `[part="error"]` of their own inside this same tree, and the kit is light DOM — a scoped rule on that name would restyle the token field\'s refusal line too.',margin:"0",color:"var(--danger)",lineHeight:"1.5"},'& [part="link"], & [part="install-link"]':{color:"var(--accent)",textDecoration:"underline"},"& code":{fontFamily:"var(--font-mono)",fontSize:"var(--jx-text-sm)"}},children:[{tagName:"div",attributes:{part:"body"},children:[{tagName:"div",attributes:{part:"body-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/body"},cases:{unsupported:{tagName:"p",attributes:{part:"note"},children:["This platform cannot reach the Cloudflare API. Publish by committing and pushing — your host builds ",{tagName:"code",textContent:"bunx jx build"}," and serves ",{tagName:"code",textContent:"dist/"},"."]},loading:{tagName:"p",attributes:{part:"note"},textContent:"Checking Cloudflare connection…"},lapsed:{tagName:"div",attributes:{part:"lapsed",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"note"},textContent:"Your Cloudflare connection has expired, so publishing cannot reach your account. Reconnect to restore it — this site's Pages project and its settings are untouched."},{tagName:"jx-button",$props:{variant:"accent",disabled:{$ref:"#/state/busy"}},attributes:{part:"reconnect"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/connect"},value:[]}]},children:[{tagName:"span",textContent:"${state.connectLabel}"}]}]},hosted:{tagName:"div",attributes:{part:"hosted",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"note"},textContent:"Connect your Cloudflare account to publish this site."},{tagName:"jx-button",$props:{disabled:{$ref:"#/state/busy"}},attributes:{part:"connect"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/connect"},value:[]}]},children:[{tagName:"span",textContent:"Connect Cloudflare"}]}]},stored:{tagName:"div",attributes:{part:"stored",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"note"},textContent:"A Cloudflare API token is stored on this machine, and Cloudflare did not accept it. It may have been revoked, or it may be missing the Account Settings Read and Pages Read/Write permissions."},{tagName:"div",attributes:{part:"actions"},children:[{tagName:"jx-button",$props:{disabled:{$ref:"#/state/busy"}},attributes:{part:"replace"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/replace"},value:[]}]},children:[{tagName:"span",textContent:"Replace token"}]},{tagName:"jx-button",$props:{quiet:!0},attributes:{part:"accounts"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openAccounts"},value:[]}]},children:[{tagName:"span",textContent:"Preferences › Accounts"}]}]}]},token:{tagName:"div",attributes:{part:"token-form",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"note"},textContent:"Paste a Cloudflare API token (permissions: Account Settings Read, Pages Read/Write). It is stored on this machine and only sent to the same-origin proxy — Studio never renders it back."},{tagName:"jx-field",$props:{span:!0,label:"API token"},attributes:{part:"token-row","data-field":"token"},children:[{tagName:"jx-textfield",$description:"No `value` binding, and its absence is the contract: a secret may pass through a field the reader typed it into and may never be painted into one they did not. The draft lives in the adapter's closure until Verify reads it, so nothing here — not the attribute, not the accessibility tree, not a DOM dump — has ever held it.",$props:{type:"password",placeholder:"cf_..."},attributes:{part:"token"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setToken"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"div",attributes:{part:"actions"},children:[{tagName:"jx-button",$props:{variant:"accent",disabled:{$ref:"#/state/busy"}},attributes:{part:"verify"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/verify"},value:[]}]},children:[{tagName:"span",textContent:"Verify & Connect"}]},{tagName:"jx-button",$props:{quiet:!0},attributes:{part:"accounts"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/openAccounts"},value:[]}]},children:[{tagName:"span",textContent:"Preferences › Accounts"}]}]}]},form:{tagName:"div",attributes:{part:"connect-form",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"note"},children:["Create a Cloudflare Pages project connected to this repository. Every commit then builds and publishes automatically (",{tagName:"code",textContent:"bunx jx build"},")."]},{tagName:"div",attributes:{part:"rows"},children:[{tagName:"jx-field",$props:{span:!0,label:"Account"},attributes:{part:"row","data-field":"account"},children:[{tagName:"jx-select",$props:{options:{$ref:"#/state/accountOptions"},value:{$ref:"#/state/accountId"}},attributes:{part:"account"},onchange:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setAccount"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"Pages project name"},attributes:{part:"row","data-field":"projectName"},children:[{tagName:"jx-textfield",$props:{value:{$ref:"#/state/projectName"}},attributes:{part:"project-name"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setProjectName"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"GitHub owner"},attributes:{part:"row","data-field":"owner"},children:[{tagName:"jx-textfield",$props:{value:{$ref:"#/state/owner"}},attributes:{part:"owner"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setOwner"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"GitHub repository"},attributes:{part:"row","data-field":"repo"},children:[{tagName:"jx-textfield",$props:{value:{$ref:"#/state/repo"}},attributes:{part:"repo"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setRepo"},value:[{$ref:"event#/target/value"}]}]}}]},{tagName:"jx-field",$props:{span:!0,label:"Production branch"},attributes:{part:"row","data-field":"branch"},children:[{tagName:"jx-textfield",$props:{value:{$ref:"#/state/branch"}},attributes:{part:"branch"},oninput:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/setBranch"},value:[{$ref:"event#/target/value"}]}]}}]}]},{tagName:"jx-button",$props:{variant:"accent",disabled:{$ref:"#/state/busy"}},attributes:{part:"submit"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/submit"},value:[]}]},children:[{tagName:"span",textContent:"${state.submitLabel}"}]}]},status:{tagName:"div",attributes:{part:"status",role:"none"},style:{display:"contents"},children:[{tagName:"p",attributes:{part:"status-line"},children:["Connected to Pages project ",{tagName:"strong",attributes:{part:"project-name"},textContent:"${state.deployProject}"},{tagName:"span",attributes:{part:"site-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasProductionUrl"},cases:{true:{tagName:"span",children:[" — ",{tagName:"a",attributes:{part:"link",href:"${state.productionUrl}",target:"_blank",rel:"noreferrer"},textContent:"${state.productionUrl}"}]}}}]},{tagName:"div",attributes:{part:"deployment-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasDeployment"},cases:{true:{tagName:"p",attributes:{part:"deployment"},children:["Latest deployment: ",{tagName:"strong",attributes:{part:"deployment-state"},textContent:"${state.deploymentState}"}," (${state.deploymentEnvironment}) — ",{tagName:"a",attributes:{part:"link",href:"${state.deploymentUrl}",target:"_blank",rel:"noreferrer"},textContent:"preview"}]},false:{tagName:"p",attributes:{part:"deployment"},textContent:"No deployments yet — the first commit after connecting triggers one."}}},{tagName:"p",attributes:{part:"hint"},textContent:"Publishing happens automatically on every commit."},{tagName:"div",attributes:{part:"actions"},children:[{tagName:"jx-button",$props:{disabled:{$ref:"#/state/busy"}},attributes:{part:"refresh"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/refresh"},value:[]}]},children:[{tagName:"span",textContent:"Refresh"}]},{tagName:"jx-button",$props:{variant:"negative",disabled:{$ref:"#/state/busy"}},attributes:{part:"disconnect"},onclick:{$prototype:"Function",body:[{operator:"call",target:{$ref:"#/state/disconnect"},value:[]}]},children:[{tagName:"span",textContent:"Disconnect"}]}]}]}}},{tagName:"div",attributes:{part:"failure-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/hasFailure"},cases:{true:{tagName:"p",attributes:{part:"failure"},children:["${state.failure}",{tagName:"span",attributes:{part:"pages-app-slot",role:"none"},style:{display:"contents"},$switch:{$ref:"#/state/needsPagesApp"},cases:{true:{tagName:"span",children:[" — if the Cloudflare Pages GitHub App is not installed on the repository, ",{tagName:"a",attributes:{part:"install-link",href:"${state.pagesAppUrl}",target:"_blank",rel:"noreferrer"},textContent:"install it"}," and retry."]}}}]}}}]}]};T("publish",C);var D="https://github.com/apps/cloudflare-pages/installations/new";function I(e){if(!e.supported)return"unsupported";if(e.loading)return"loading";if(e.connected&&e.lapsed)return"lapsed";if(!e.connected){if(e.hosted)return"hosted";return e.tokenStored&&!e.replacing?"stored":"token"}return e.deploy?"status":"form"}function w(e){let{error:t}=e;return{accountId:e.form.accountId,accountOptions:e.accounts,body:I(e),branch:e.form.branch,busy:e.busy,connectLabel:e.busy?"Reconnecting…":"Reconnect Cloudflare",deploymentEnvironment:e.deployment?.environment??"",deploymentState:e.deployment?`${e.deployment.stage}: ${e.deployment.status}`:"",deploymentUrl:e.deployment?.url??"",deployProject:e.deploy?.projectName??"",failure:t,hasDeployment:e.deployment!==null,hasFailure:t!=="",hasProductionUrl:(e.deploy?.productionUrl??"")!=="",needsPagesApp:/github/i.test(t)&&/app|install|source|repo/i.test(t),owner:e.form.owner,pagesAppUrl:D,productionUrl:e.deploy?.productionUrl??"",projectName:e.form.projectName,repo:e.form.repo,submitLabel:e.busy?"Connecting…":"Create & Connect"}}function j(e){let t=document.createElement("div");t.style.pointerEvents="auto",e.layer.append(t);let n="",m=!1,N=()=>{if(m)return;m=!0,e.onClosed()},P=()=>m,d=g({...w(e.view),closed:N,connect:()=>{e.onConnect()},disconnect:()=>{e.onDisconnect()},openAccounts:()=>{e.onOpenAccounts()},refresh:()=>{e.onRefresh()},replace:()=>{n="",e.onReplaceToken()},setAccount:(o)=>{d.accountId=o,e.onField("accountId",o)},setBranch:(o)=>{d.branch=o,e.onField("branch",o)},setOwner:(o)=>{d.owner=o,e.onField("owner",o)},setProjectName:(o)=>{d.projectName=o,e.onField("projectName",o)},setRepo:(o)=>{d.repo=o,e.onField("repo",o)},setToken:(o)=>{n=o},submit:()=>{e.onSubmit()},verify:()=>{let o=n;n="",e.onSaveToken(o)}}),y=null,A=R("publish",d,t).then(async(o)=>{y=o;let u=o.root;if(P())return o.dispose(),u;if(await Yt(u),P())return u;return(u.querySelector('dialog[part="dialog"]')??u).setAttribute(Ue,ft("modal","publish")),Ot(u),u});return{close(){let o=y?.root;if(o instanceof HTMLElement)Nt(o);y?.dispose(),y=null,n="",t.remove(),N()},host:t,ready:A,update(o){Object.assign(d,w(o))}}}var f=null,i="loading",h=[],l=null,r="",c=!1,b=!1,a={accountId:"",branch:"main",owner:"",projectName:"",repo:""};function x(){return S?.projectConfig??null}function O(e){return e.toLowerCase().replaceAll(/[^a-z0-9]+/g,"-").replaceAll(/^-+|-+$/g,"").slice(0,58)||"site"}function H(){let e=p().projectRoot,t=/^([\w.-]+)\/([\w.-]+)(?:@.+)?$/.exec(e);return t?{owner:t[1],repo:t[2]}:{owner:"",repo:""}}function L(){let e=/^[\w.-]+\/[\w.-]+@[^:]+:(.+)$/.exec(p().projectRoot)?.[1]??"";return Rl(e)??""}function U(){let e=Ri();return e?{productionUrl:e.productionUrl??"",projectName:e.projectName}:null}function k(){let e=zl(),t=i==="loading"?null:i;return{accounts:h.map((n)=>({label:n.name,value:n.id})),busy:c,connected:t?.connected===!0,deploy:U(),deployment:l?{environment:l.environment,stage:l.stage,status:l.status,url:l.url}:null,error:r,form:{...a},hosted:e&&Q(p().cfConnect),lapsed:t?.connected===!0&&t.needsReconnect===!0,loading:i==="loading",replacing:b,supported:e,tokenStored:db()!==""}}function s(){if(f){f.update(k());return}f=j({layer:tt("modal"),onClosed:B,onConnect:()=>{M()},onDisconnect:()=>{z()},onField:(e,t)=>{a={...a,[e]:t}},onOpenAccounts:_,onRefresh:()=>{v()},onReplaceToken:()=>{b=!0,r="",s()},onSaveToken:(e)=>{E(e)},onSubmit:()=>{V()},view:k()})}async function v(){i="loading",s();try{if(i=await p().cfConnection?.()??null,i?.connected&&!i.needsReconnect){h=await cN(),a={...a,accountId:i.accountId??h[0]?.id??""};let e=Ri();if(e)l=await Cb(e),Ad(l)}}catch(e){i=null,r=e instanceof Error?e.message:String(e)}s()}async function E(e){let t=e.trim();if(!t){r="Paste a token, or use Preferences › Accounts to forget the stored one.",s();return}DE(t),b=!1,r="",await v()}function _(){ae()?.run("app.preferences",{section:"accounts"})}async function M(){c=!0,r="",s();try{let e=await p().cfConnect?.()??null;if(e?.status==="timeout")r="The Cloudflare window didn't finish. Sign in there, then reconnect — nothing was changed.";else if(e?.status==="connected"&&!e.connection.accountId){let{openCfAccountPicker:t}=await (le("z1sgwpwd"),import("./cf-account-picker-z1sgwpwd.js"));await t()}}catch(e){r=e instanceof Error?e.message:String(e)}c=!1,ds(),await v()}async function V(){let e=x();if(!e)return;if(!a.projectName||!a.owner||!a.repo||!a.accountId){r="Account, project name, and the GitHub owner/repo are all required.",s();return}c=!0,r="",s();try{let t=L(),n={accountId:a.accountId,owner:a.owner,productionBranch:a.branch||"main",projectName:a.projectName,repo:a.repo};if(t)n.rootDir=t;let m=await dN(e,n);l=await Cb(m).catch(()=>null)}catch(t){r=t instanceof Error?t.message:String(t)}c=!1,s()}async function z(){let e=x();if(!e)return;c=!0,s();try{await qT(e,null),l=null}catch(t){r=t instanceof Error?t.message:String(t)}c=!1,s()}function B(){let e=f;f=null,e?.close()}function wk(e){i={accountId:e.accountId??"demo-account",connected:!0},h=[],l=e.deployment,Ad(e.deployment),r="",c=!1,b=!1,s()}function Y2(){let e=x(),{owner:t,repo:n}=H();i="loading",h=[],l=null,r="",c=!1,b=!1,a={accountId:"",branch:"main",owner:t,projectName:Ri()?.projectName??O(e?.name??""),repo:n},s(),v()}
|
|
2
|
-
export{Rl,wk,Y2};
|
|
3
|
-
|
|
4
|
-
//# debugId=08098811DFDE35A764756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-yhz5b313.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
function n(e){return typeof e==="string"}function Z(e){return typeof e==="number"}function Ze(e){return typeof e==="boolean"}function cM(e){return typeof e==="bigint"}function Iv(e){return typeof e==="symbol"}function Q(e){return typeof e==="function"}function _(e){return typeof e==="object"&&e!==null}function lf(e){return e===null||n(e)||Z(e)||Ze(e)}function v(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Me(e){return v(e)&&typeof e.$ref==="string"}function Oa(e){return v(e)&&e.$prototype==="Function"}function tc(e){return v(e)&&v(e.$expression)}function Xx(e){return tc(e)&&Array.isArray(e.parameters)&&e.parameters.length>0}function cI(e){return Oa(e)&&Array.isArray(e.body)}function Rv(e){return v(e)&&typeof e.$prototype==="string"&&e.$prototype!=="Function"}function dI(e){return v(e)&&e.timing==="server"&&typeof e.$src==="string"&&typeof e.$export==="string"&&!e.$prototype}function Go(e){return v(e)&&e.$prototype==="Array"}function Gn(e){return v(e)}function Ma(e){return typeof e==="string"&&e.includes("${")}function uI(e){return/\breturn\b[^\S\n]*(?![;}\s]|$)/.test(e)}function hl(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Di(e,t){let r=e?.[t];return hl(r)?r:void 0}function td(e,t){let r=e[t];if(hl(r))return r;let o={};return e[t]=o,o}function cf(e){return Me(e)||Oa(e)||tc(e)}function Zm(e,t){let r=e[t];return cf(r)?r:void 0}function Qx(e){if(!e)return[];return e.map((t)=>n(t)?t:t.name)}function i(e){return typeof e==="string"}function $h(e){if(typeof e!=="object"||e===null||Array.isArray(e)||!v(e.$expression))return!1;let t=e.$expression;if(t.operator==="?:")return typeof t.value==="string"&&typeof t.initial==="string";if(t.operator==="switch")return v(t.cases)&&Object.values(t.cases).every((r)=>n(r))&&typeof t.default==="string";return!1}function hI(e){if(i(e))return[e];if(!$h(e))return[];let t=e.$expression;if(t.operator==="?:")return[...new Set([t.value,t.initial])];return[...new Set([...Object.values(t.cases),t.default])]}function it(e){return i(e)?e:hI(e).join("|")}function nd(e){return e.startsWith("#")}
|
|
2
|
-
export{n,Z,Ze,cM,Iv,Q,_,lf,v,Me,Oa,tc,Xx,cI,Rv,dI,Go,Gn,Ma,uI,hl,Di,td,cf,Zm,Qx,$h,hI,it,nd};
|
|
3
|
-
|
|
4
|
-
//# debugId=6F8E7B2F3F28545E64756E2164756E21
|
|
5
|
-
//# sourceMappingURL=studio-zsjpsw08.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{pi,zm,z$,m,h,Gr,pn,Zl,kr,Wm,EC,TC,Xl,Vm,Um,LC,$C,IC,qm,yh,Ql,qp,Kd,RC,_i,Zc,DC,jx,W$,Jd,V$,U$,jt,mv,Hx,q$}from"./studio-j933k8nr.js";import"./studio-yg5n49za.js";import"./studio-4nkm4404.js";import"./studio-ahf3cspq.js";import"./studio-848rk4p1.js";import"./studio-w67vfgy5.js";export{z$ as MAX_PANES,pi as PRIMARY_PANE,zm as SECONDARY_PANE,jt as activateTab,Gr as activePane,h as activeTab,RC as clearPaneActiveTab,V$ as closeAllTabs,Vm as closePane,Jd as closeTab,qm as detachTab,kr as focusPane,yh as insertIntoPane,Wm as isPaneFocused,qp as isTabActive,W$ as moveTab,mv as moveTabToPane,_i as openTab,TC as paneBeside,pn as paneById,Um as paneIsEmpty,Zl as paneOfTab,DC as promoteDirtyPreviewTabs,Zc as promoteTab,Xl as receivingPane,q$ as registerTabCommands,Hx as renameTab,U$ as replaceAllTabs,IC as setCloseLanding,$C as setEmptyPaneFallback,jx as setTabPinned,LC as setTabScope,Ql as setWorkspaceProject,EC as splitRight,Kd as tabIsLive,m as workspace};
|
|
2
|
-
|
|
3
|
-
//# debugId=B708A93419855CFB64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=workspace-d65bz1qk.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{E2,n_,bk,vk,i_,jg,yk}from"./studio-k4xc5g6h.js";import"./studio-ch8gt8vt.js";import"./studio-vffwe9k7.js";import"./studio-rf8d6p9f.js";import"./studio-jgbvqcgh.js";import"./studio-bkmv1h3e.js";import"./studio-zacvfm31.js";import"./studio-thj81e98.js";import"./studio-4zqfw5ha.js";import"./studio-56egy6vf.js";import"./studio-fyf7j57j.js";import"./studio-mwnmzx7g.js";import"./studio-vxjap704.js";import"./studio-fep7hr66.js";import"./studio-cqf1k4qk.js";import"./studio-76t560kn.js";import"./studio-pmzg17fj.js";import"./studio-5e7p1vgd.js";import"./studio-ga77mf07.js";import"./studio-6vwvshw8.js";import"./studio-5m0w815d.js";import"./studio-vcz63n42.js";import"./studio-qyb5bebs.js";import"./studio-zxm98z2m.js";import"./studio-ggm7zf70.js";import"./studio-695k95bw.js";import"./studio-nf0pqpbj.js";import"./studio-dbgv4fv9.js";import"./studio-va0e63sk.js";import"./studio-20ap8dds.js";import"./studio-5dmgmyw4.js";import"./studio-8x8616xd.js";import"./studio-xebavr9s.js";import"./studio-cvz0e00f.js";import"./studio-x2metr13.js";import"./studio-f2j9et3h.js";import"./studio-dy2xtt7a.js";import"./studio-0hr000ba.js";import"./studio-pd9dsqpq.js";import"./studio-j933k8nr.js";import"./studio-yg5n49za.js";import"./studio-4nkm4404.js";import"./studio-ahf3cspq.js";import"./studio-et6t8g4m.js";import"./studio-848rk4p1.js";import"./studio-w67vfgy5.js";import"./studio-k1wvtp03.js";export{E2 as WORKSPACE_HOME_MODE_SET,jg as detachWorkspaceHome,n_ as isWorkspaceHomeMode,bk as openWorkspaceHome,vk as placeWorkspaceHome,yk as renderWorkspaceHome,i_ as workspaceHomeMounted};
|
|
2
|
-
|
|
3
|
-
//# debugId=4F4CC8DDA0EAF06264756E2164756E21
|
|
4
|
-
//# sourceMappingURL=workspace-home-vbg9b3jh.js.map
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
/**
|
|
3
|
-
* Project Settings as a dialog (§17.1): the flow that opens it, mounts the settings editor into it,
|
|
4
|
-
* and takes both down.
|
|
5
|
-
*
|
|
6
|
-
* Project Settings was a document in the pane, the `project.json` tab under a `settings` editor
|
|
7
|
-
* mode. The five workspaces made that the wrong home: a tab belongs to exactly one workspace, and
|
|
8
|
-
* configuration belongs to all of them, so a settings TAB either pulled the author out of the
|
|
9
|
-
* workspace they were in or had to be special-cased in every one. A dialog is reachable from every
|
|
10
|
-
* workspace and leaves the one underneath where it was. What made the old modal a problem (a form
|
|
11
|
-
* that hid the canvas it was tuning) left with the design tokens, which are the Styles workspace's
|
|
12
|
-
* now; every section still here writes `project.json` as it is edited, through the one chokepoint
|
|
13
|
-
* (`tabs/project-config.ts`), so the dialog has nothing to confirm and its one answer is Close.
|
|
14
|
-
*
|
|
15
|
-
* **Which section shows is the registry's, not this module's.** `settings/section-registry.ts`
|
|
16
|
-
* holds the requested and the displayed section and outlives the dialog, which is what makes the
|
|
17
|
-
* dialog reopen where the author left it for the rest of the session.
|
|
18
|
-
*
|
|
19
|
-
* Modality, Escape and focus restoration are the platform's: a `jx-dialog` in the dialog layer,
|
|
20
|
-
* opened with `showModal()`, which puts focus back on whatever opened it when it closes.
|
|
21
|
-
*
|
|
22
|
-
* **The frame and the editor are built once per session** and kept, closed, in the dialog layer. A
|
|
23
|
-
* close suspends the editor (it stops following the section registry) and closes the platform's
|
|
24
|
-
* dialog; an open resumes it, which redraws the current section, and shows the same dialog again.
|
|
25
|
-
* Rebuilding both on every open was most of what opening Settings cost, and disposing them inside
|
|
26
|
-
* the dialog's own `cancel` handler removed a subtree that still held focus from the top layer,
|
|
27
|
-
* which the browser re-styled on the way out. {@link disposeSettingsDialog} is the teardown, and a
|
|
28
|
-
* frame whose layer was replaced under it is rebuilt rather than shown.
|
|
29
|
-
*
|
|
30
|
-
* @docs studio/projects/settings
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
import { activeRegistry } from "../commands/active-registry";
|
|
34
|
-
import { runActiveReported } from "../commands/run-reported";
|
|
35
|
-
import { mountSettingsPane } from "../panels/settings-pane";
|
|
36
|
-
import { openSettingsDialogSurface } from "../surfaces/settings-dialog";
|
|
37
|
-
import { layerHost } from "../ui/layers";
|
|
38
|
-
import type { SettingsPaneMount } from "../panels/settings-pane";
|
|
39
|
-
import type { SettingsDialogHandle } from "../surfaces/settings-dialog";
|
|
40
|
-
import type { InspectorTabId } from "../shell";
|
|
41
|
-
import type { WorkspaceId } from "../workspace/workspace-ids";
|
|
42
|
-
import type { StylesView } from "../style/project-styles";
|
|
43
|
-
import type { PublishTab } from "../publish/publish-ids";
|
|
44
|
-
|
|
45
|
-
/** The frame, built on the first open and kept across closes; `null` before then. */
|
|
46
|
-
interface SettingsFrame {
|
|
47
|
-
dialog: SettingsDialogHandle;
|
|
48
|
-
/** The editor in the frame's body, once the body has been created. */
|
|
49
|
-
pane: SettingsPaneMount | null;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let _frame: SettingsFrame | null = null;
|
|
53
|
-
|
|
54
|
-
/** Whether the dialog is asked to be up: true from an open until the close that ends it. */
|
|
55
|
-
let _open = false;
|
|
56
|
-
|
|
57
|
-
/** {@link _open}, read through a call so a check after an `await` is not narrowed to before it. */
|
|
58
|
-
function isOpen(): boolean {
|
|
59
|
-
return _open;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** Build the frame (it opens itself once mounted). */
|
|
63
|
-
function buildFrame(): SettingsFrame {
|
|
64
|
-
const frame: SettingsFrame = {
|
|
65
|
-
dialog: openSettingsDialogSurface({
|
|
66
|
-
body: (host) => {
|
|
67
|
-
frame.pane = mountSettingsPane(host, {
|
|
68
|
-
openMoved: (workspace, inspector, view, publishTab) => {
|
|
69
|
-
void openMoved(workspace, inspector, view, publishTab);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
},
|
|
73
|
-
/* Escape or Close: the platform closed the dialog, so the flow follows. `close()` is
|
|
74
|
-
idempotent, so the flow's own close running first is fine. */
|
|
75
|
-
closed: () => {
|
|
76
|
-
if (_frame === frame) {
|
|
77
|
-
closeSettingsDialog();
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
layer: layerHost("dialog"),
|
|
81
|
-
}),
|
|
82
|
-
pane: null,
|
|
83
|
-
};
|
|
84
|
-
return frame;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Leave Settings for the workspace something moved to: the Moved footnote's buttons.
|
|
89
|
-
*
|
|
90
|
-
* Closed FIRST, so the workspace the author asked for is what they see and focus returns to the
|
|
91
|
-
* frame rather than to a row that is going away. A refusal (the switch is gated on an open project)
|
|
92
|
-
* is filed in Problems under this surface's name instead of being dropped.
|
|
93
|
-
*
|
|
94
|
-
* A row that names an Inspector tab ("Head and SEO defaults → Page tab") also shows the Inspector
|
|
95
|
-
* on that tab, AFTER the switch, because entering a workspace applies its frame preset and would
|
|
96
|
-
* otherwise put the dock back as the preset has it. The tab is a document-level view, so with no
|
|
97
|
-
* document open there is no tab to show and asking would only file a refusal; the dock is still
|
|
98
|
-
* opened, which is where the tab appears once one is.
|
|
99
|
-
*
|
|
100
|
-
* A row that names a Styles view ("Colors and fonts → Styles › Variables") runs `styles.open` with
|
|
101
|
-
* that view instead, which is the same workspace switch followed by the view.
|
|
102
|
-
*
|
|
103
|
-
* @param {WorkspaceId} workspace
|
|
104
|
-
* @param {InspectorTabId} [inspector]
|
|
105
|
-
* @param {StylesView} [view]
|
|
106
|
-
* @returns {Promise<void>} Settles once every command the row runs has settled
|
|
107
|
-
*/
|
|
108
|
-
async function openMoved(
|
|
109
|
-
workspace: WorkspaceId,
|
|
110
|
-
inspector?: InspectorTabId,
|
|
111
|
-
view?: StylesView,
|
|
112
|
-
publishTab?: PublishTab,
|
|
113
|
-
): Promise<void> {
|
|
114
|
-
closeSettingsDialog();
|
|
115
|
-
if (view !== undefined) {
|
|
116
|
-
await runActiveReported("styles.open", { view }, "Settings");
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
// Hosting is a Publish sub-tab, not the workspace's first: the button says where it lands.
|
|
120
|
-
if (publishTab !== undefined) {
|
|
121
|
-
await runActiveReported("publish.open", { tab: publishTab }, "Settings");
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
await runActiveReported("view.setWorkspace", { workspace }, "Settings");
|
|
125
|
-
if (inspector === undefined) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
await runActiveReported("view.setRightPanel", { open: true }, "Settings");
|
|
129
|
-
if (activeRegistry()?.isEnabled("view.setRightTab") === true) {
|
|
130
|
-
await runActiveReported("view.setRightTab", { tab: inspector }, "Settings");
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Open Project Settings, or leave it up when it already is.
|
|
136
|
-
*
|
|
137
|
-
* Re-opening while it is up does not stack a second dialog: the section the caller asked for has
|
|
138
|
-
* already been written to the registry, which redraws the editor that is showing.
|
|
139
|
-
*
|
|
140
|
-
* @returns {Promise<void>} Settles once the dialog is showing and the current section's row holds
|
|
141
|
-
* the keyboard
|
|
142
|
-
*/
|
|
143
|
-
export async function openSettingsDialog(): Promise<void> {
|
|
144
|
-
if (_open && _frame) {
|
|
145
|
-
await _frame.dialog.ready;
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
_open = true;
|
|
149
|
-
// A frame whose layer went away (a shell remount) is dead weight, not something to show.
|
|
150
|
-
if (_frame && !_frame.dialog.host.isConnected) {
|
|
151
|
-
disposeSettingsDialog();
|
|
152
|
-
_open = true;
|
|
153
|
-
}
|
|
154
|
-
let frame = _frame;
|
|
155
|
-
if (frame) {
|
|
156
|
-
frame.pane?.resume();
|
|
157
|
-
await frame.dialog.show();
|
|
158
|
-
} else {
|
|
159
|
-
frame = buildFrame();
|
|
160
|
-
_frame = frame;
|
|
161
|
-
await frame.dialog.ready;
|
|
162
|
-
}
|
|
163
|
-
/* Read after the wait, from the frame: the body is created while the dialog mounts, and a close
|
|
164
|
-
in between leaves the editor built but not to be focused. */
|
|
165
|
-
const mounted = frame.pane;
|
|
166
|
-
if (mounted === null || _frame !== frame || !isOpen()) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
await mounted.ready;
|
|
170
|
-
if (_frame === frame && isOpen()) {
|
|
171
|
-
mounted.focusActive();
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/** Close Project Settings if it is open. Idempotent. The frame stays built for the next open. */
|
|
176
|
-
export function closeSettingsDialog(): void {
|
|
177
|
-
if (!_open) {
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
_open = false;
|
|
181
|
-
_frame?.pane?.suspend();
|
|
182
|
-
_frame?.dialog.close();
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** Close Project Settings and take its frame and editor down. Idempotent. */
|
|
186
|
-
export function disposeSettingsDialog(): void {
|
|
187
|
-
_open = false;
|
|
188
|
-
const frame = _frame;
|
|
189
|
-
_frame = null;
|
|
190
|
-
frame?.pane?.dispose();
|
|
191
|
-
frame?.dialog.dispose();
|
|
192
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
-
"$id": "StudioSettingsDialog",
|
|
4
|
-
"$description": "Project Settings (§17.1): a `jx-dialog` whose body is the settings editor's two columns, the grouped section list and the section body. The dialog owns modality, Escape and focus restoration, and its one footer answer is Close: every section writes as it is edited, so there is nothing to confirm or cancel. The body is an ISLAND: this document draws the slot and nothing in it, and `settings/settings-dialog.ts` mounts `settings-pane.json` there through `onNodeCreated` (studio-ui-guidelines.md §9.4).",
|
|
5
|
-
"tagName": "jx-dialog",
|
|
6
|
-
"$props": {
|
|
7
|
-
"headline": "Project settings",
|
|
8
|
-
"confirmLabel": "",
|
|
9
|
-
"cancelLabel": "Close",
|
|
10
|
-
"size": "xl"
|
|
11
|
-
},
|
|
12
|
-
"attributes": {
|
|
13
|
-
"part": "settings"
|
|
14
|
-
},
|
|
15
|
-
"oncancel": {
|
|
16
|
-
"$prototype": "Function",
|
|
17
|
-
"body": [
|
|
18
|
-
{
|
|
19
|
-
"operator": "call",
|
|
20
|
-
"target": {
|
|
21
|
-
"$ref": "#/state/closed"
|
|
22
|
-
},
|
|
23
|
-
"value": []
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
"onclose": {
|
|
28
|
-
"$prototype": "Function",
|
|
29
|
-
"body": [
|
|
30
|
-
{
|
|
31
|
-
"operator": "call",
|
|
32
|
-
"target": {
|
|
33
|
-
"$ref": "#/state/closed"
|
|
34
|
-
},
|
|
35
|
-
"value": []
|
|
36
|
-
}
|
|
37
|
-
]
|
|
38
|
-
},
|
|
39
|
-
"children": [
|
|
40
|
-
{
|
|
41
|
-
"tagName": "div",
|
|
42
|
-
"attributes": {
|
|
43
|
-
"part": "pane-slot"
|
|
44
|
-
},
|
|
45
|
-
"style": {
|
|
46
|
-
"$description": "The editor's box is its own (`settings-pane.json`); the slot only gives it the dialog body's width.",
|
|
47
|
-
"minWidth": "0"
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/// <reference lib="dom" />
|
|
2
|
-
/**
|
|
3
|
-
* The Project Settings dialog, as a mounted document.
|
|
4
|
-
*
|
|
5
|
-
* A `jx-dialog` in the dialog layer whose body is an island: `settings-dialog.json` draws the slot,
|
|
6
|
-
* and the flow (`settings/settings-dialog.ts`) mounts the settings editor's columns into it through
|
|
7
|
-
* the `onNodeCreated` seam (`studio-ui-guidelines.md` §9.4). The dialog is only the frame and the
|
|
8
|
-
* one answer, Close.
|
|
9
|
-
*
|
|
10
|
-
* **Mounted once, shown many times.** Every open used to mount this document and the whole editor
|
|
11
|
-
* into it, and every close disposed both while the dialog was still on the top layer, which made
|
|
12
|
-
* each close re-style the subtree it was removing. Now a close is the platform's `close()` and the
|
|
13
|
-
* document stays in the dialog layer, closed (so `display: none`, and inert), until the flow
|
|
14
|
-
* disposes it; the next open is one `showModal()`.
|
|
15
|
-
*
|
|
16
|
-
* **Await the ELEMENT, not just the mount.** `mountSurface` resolving means the document rendered;
|
|
17
|
-
* a `jx-dialog`'s own template is one `connectedCallback` later, and `showModal` in between finds
|
|
18
|
-
* no `<dialog>` to open. `whenReady` is shared with `surfaces/dialog.ts`.
|
|
19
|
-
*
|
|
20
|
-
* @docs studio/projects/settings
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { isString } from "@jxsuite/schema/guards";
|
|
24
|
-
import { close, showModal } from "@jxsuite/ui/behaviors/dialog";
|
|
25
|
-
import { reactive } from "../reactivity";
|
|
26
|
-
import { overlayRegion, REGION_ATTR } from "../ui/regions";
|
|
27
|
-
import { mountSurface, registerSurface } from "../ui/surface";
|
|
28
|
-
import { whenReady } from "./dialog";
|
|
29
|
-
import settingsDialogDoc from "./settings-dialog.json";
|
|
30
|
-
import type { JxElement } from "@jxsuite/schema/types";
|
|
31
|
-
import type { SurfaceHandle } from "../ui/surface";
|
|
32
|
-
|
|
33
|
-
registerSurface("settings-dialog", settingsDialogDoc);
|
|
34
|
-
|
|
35
|
-
/** The dialog's region: `overlay.dialog:settings`. Section regions are named under it. */
|
|
36
|
-
export const SETTINGS_DIALOG_REGION = overlayRegion("dialog", "settings");
|
|
37
|
-
|
|
38
|
-
export interface SettingsDialogOptions {
|
|
39
|
-
/** The dialog layer host, handed in so this module never reaches back into `layers.ts`. */
|
|
40
|
-
layer: HTMLElement;
|
|
41
|
-
/** The body slot was created: where the flow mounts the settings editor. Called once. */
|
|
42
|
-
body: (host: HTMLElement) => void;
|
|
43
|
-
/** The dialog closed, for any reason: once per time it was shown. */
|
|
44
|
-
closed: () => void;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* The settings frame, mounted once and shown as often as it is asked for.
|
|
49
|
-
*
|
|
50
|
-
* Closing it closes the platform's `<dialog>` and leaves the document standing in the dialog layer,
|
|
51
|
-
* so the next open is one `showModal()` on a frame whose editor is already built, not a mount of
|
|
52
|
-
* the whole editor. Only {@link SettingsDialogHandle.dispose} takes it down.
|
|
53
|
-
*/
|
|
54
|
-
export interface SettingsDialogHandle {
|
|
55
|
-
/** The slot in the dialog layer that carries the region. */
|
|
56
|
-
host: HTMLElement;
|
|
57
|
-
/** Resolves with the `jx-dialog` element once it has rendered (and been opened, if still asked). */
|
|
58
|
-
ready: Promise<HTMLElement>;
|
|
59
|
-
/** Show it again after a close. Resolves once it is showing. */
|
|
60
|
-
show: () => Promise<HTMLElement>;
|
|
61
|
-
/** Close the dialog (the platform restores focus); the document stays mounted. Idempotent. */
|
|
62
|
-
close: () => void;
|
|
63
|
-
/** Close it and take the document and its slot down for good. Idempotent. */
|
|
64
|
-
dispose: () => void;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
interface SettingsDialogScope {
|
|
68
|
-
closed: () => void;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** The `part` a node's definition carries, or `""` for a text node or an unmarked element. */
|
|
72
|
-
function partOf(def: JxElement | string): string {
|
|
73
|
-
const part = isString(def) ? undefined : def.attributes?.["part"];
|
|
74
|
-
return isString(part) ? part : "";
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Mount the dialog and open it. The handle's `ready` resolves once it is showing.
|
|
79
|
-
*
|
|
80
|
-
* @param {SettingsDialogOptions} options
|
|
81
|
-
* @returns {SettingsDialogHandle}
|
|
82
|
-
*/
|
|
83
|
-
export function openSettingsDialogSurface(options: SettingsDialogOptions): SettingsDialogHandle {
|
|
84
|
-
const slot = document.createElement("div");
|
|
85
|
-
/* The layer is `pointer-events: none` so a click passes through it when nothing is up, and every
|
|
86
|
-
slot in it turns them back on for its own content. `pointer-events` INHERITS, and the top layer
|
|
87
|
-
changes paint order rather than inheritance, so a modal `<dialog>` in a slot that skipped this
|
|
88
|
-
is painted above everything and hit-tests to nothing. */
|
|
89
|
-
slot.style.pointerEvents = "auto";
|
|
90
|
-
options.layer.append(slot);
|
|
91
|
-
|
|
92
|
-
/** Whether the dialog is asked to be showing: true from each open until its close. */
|
|
93
|
-
let wanted = true;
|
|
94
|
-
let disposed = false;
|
|
95
|
-
/** Say this showing is over, once: the platform's own `close` and `close()` can each be first. */
|
|
96
|
-
const finish = (): void => {
|
|
97
|
-
if (!wanted) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
wanted = false;
|
|
101
|
-
options.closed();
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const scope = reactive<SettingsDialogScope>({ closed: finish });
|
|
105
|
-
|
|
106
|
-
let mounted: SurfaceHandle | null = null;
|
|
107
|
-
/** Open the platform's dialog, if it is still asked for. Read through a call after each await. */
|
|
108
|
-
const open = (element: HTMLElement): HTMLElement => {
|
|
109
|
-
if (!disposed && wanted) {
|
|
110
|
-
showModal(element);
|
|
111
|
-
}
|
|
112
|
-
return element;
|
|
113
|
-
};
|
|
114
|
-
const ready = mountSurface("settings-dialog", scope, slot, {
|
|
115
|
-
onNodeCreated: (element, _path, def) => {
|
|
116
|
-
if (!disposed && element instanceof HTMLElement && partOf(def) === "pane-slot") {
|
|
117
|
-
options.body(element);
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
}).then(async (surface) => {
|
|
121
|
-
/* SAFETY: `settings-dialog.json`'s root definition is a `jx-dialog` element, so the runtime
|
|
122
|
-
mounts an HTMLElement. */
|
|
123
|
-
const element = surface.root as HTMLElement;
|
|
124
|
-
if (disposed) {
|
|
125
|
-
surface.dispose();
|
|
126
|
-
return element;
|
|
127
|
-
}
|
|
128
|
-
mounted = surface;
|
|
129
|
-
await whenReady(element);
|
|
130
|
-
/* The region goes on the platform's own `<dialog>`, the one element here that HAS a box:
|
|
131
|
-
`jx-dialog` is `display: contents`, and the slot wraps a dialog the top layer takes out of
|
|
132
|
-
flow, so both measure 0×0, and a region whose box is empty is refused by the screenshot
|
|
133
|
-
pipeline. The kit's own behaviour sidecar finds that node by exactly this selector. */
|
|
134
|
-
const box = element.querySelector<HTMLElement>('dialog[part="dialog"]') ?? element;
|
|
135
|
-
box.setAttribute(REGION_ATTR, SETTINGS_DIALOG_REGION);
|
|
136
|
-
return open(element);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
const hide = (): void => {
|
|
140
|
-
const element = mounted?.root;
|
|
141
|
-
if (element instanceof HTMLElement) {
|
|
142
|
-
// The platform's close, so focus goes back where it came from before anything else moves.
|
|
143
|
-
close(element);
|
|
144
|
-
}
|
|
145
|
-
finish();
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
close: hide,
|
|
150
|
-
dispose() {
|
|
151
|
-
if (disposed) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
hide();
|
|
155
|
-
disposed = true;
|
|
156
|
-
mounted?.dispose();
|
|
157
|
-
mounted = null;
|
|
158
|
-
slot.remove();
|
|
159
|
-
},
|
|
160
|
-
host: slot,
|
|
161
|
-
ready,
|
|
162
|
-
show() {
|
|
163
|
-
if (!disposed) {
|
|
164
|
-
wanted = true;
|
|
165
|
-
}
|
|
166
|
-
return ready.then(open);
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
}
|