@jxsuite/studio 0.16.0 → 0.17.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/studio.js +466 -126
- package/dist/studio.js.map +19 -14
- package/package.json +1 -1
- package/src/browse/browse.js +24 -3
- package/src/canvas/canvas-live-render.js +1 -27
- package/src/editor/shortcuts.js +7 -0
- package/src/files/files.js +7 -2
- package/src/panels/panel-events.js +24 -19
- package/src/panels/properties-panel.js +14 -14
- package/src/panels/quick-search.js +170 -0
- package/src/panels/toolbar.js +62 -13
- package/src/platforms/devserver.js +12 -0
- package/src/recent-projects.js +57 -0
- package/src/studio.js +58 -9
- package/src/ui/spectrum.js +2 -0
- package/src/workspace/workspace.js +44 -0
package/dist/studio.js
CHANGED
|
@@ -1508,8 +1508,10 @@ var init_tab = __esm(() => {
|
|
|
1508
1508
|
var exports_workspace = {};
|
|
1509
1509
|
__export(exports_workspace, {
|
|
1510
1510
|
workspace: () => workspace,
|
|
1511
|
+
replaceAllTabs: () => replaceAllTabs,
|
|
1511
1512
|
openTab: () => openTab,
|
|
1512
1513
|
closeTab: () => closeTab,
|
|
1514
|
+
closeAllTabs: () => closeAllTabs,
|
|
1513
1515
|
activeTab: () => activeTab,
|
|
1514
1516
|
activateTab: () => activateTab
|
|
1515
1517
|
});
|
|
@@ -1531,6 +1533,32 @@ function closeTab(tabId) {
|
|
|
1531
1533
|
workspace.activeTabId = workspace.tabOrder[workspace.tabOrder.length - 1] || null;
|
|
1532
1534
|
}
|
|
1533
1535
|
}
|
|
1536
|
+
function closeAllTabs() {
|
|
1537
|
+
const tabs = [...workspace.tabs.values()];
|
|
1538
|
+
workspace.tabs.clear();
|
|
1539
|
+
workspace.tabOrder = [];
|
|
1540
|
+
workspace.activeTabId = null;
|
|
1541
|
+
for (const tab of tabs) {
|
|
1542
|
+
disposeTab(tab);
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
function replaceAllTabs(newTabOpts) {
|
|
1546
|
+
const oldIds = [...workspace.tabs.keys()];
|
|
1547
|
+
const oldTabs = [...workspace.tabs.values()];
|
|
1548
|
+
const newTab = createTab(newTabOpts);
|
|
1549
|
+
workspace.tabs.set(newTab.id, newTab);
|
|
1550
|
+
workspace.activeTabId = newTab.id;
|
|
1551
|
+
workspace.tabOrder = [newTab.id];
|
|
1552
|
+
for (const id of oldIds) {
|
|
1553
|
+
if (id === newTab.id)
|
|
1554
|
+
continue;
|
|
1555
|
+
workspace.tabs.delete(id);
|
|
1556
|
+
}
|
|
1557
|
+
for (const tab of oldTabs) {
|
|
1558
|
+
disposeTab(tab);
|
|
1559
|
+
}
|
|
1560
|
+
return newTab;
|
|
1561
|
+
}
|
|
1534
1562
|
function activateTab(tabId) {
|
|
1535
1563
|
if (workspace.tabs.has(tabId))
|
|
1536
1564
|
workspace.activeTabId = tabId;
|
|
@@ -176970,12 +176998,6 @@ async function codeService(action, payload) {
|
|
|
176970
176998
|
return null;
|
|
176971
176999
|
return platform3.codeService(action, payload);
|
|
176972
177000
|
}
|
|
176973
|
-
async function locateDocument(name) {
|
|
176974
|
-
const platform3 = getPlatform();
|
|
176975
|
-
if (!platform3.locateFile)
|
|
176976
|
-
return null;
|
|
176977
|
-
return platform3.locateFile(name);
|
|
176978
|
-
}
|
|
176979
177001
|
var pluginSchemaCache = new Map;
|
|
176980
177002
|
async function fetchPluginSchema(def3, state) {
|
|
176981
177003
|
if (!def3.$src || !def3.$prototype)
|
|
@@ -177034,58 +177056,6 @@ function getFunctionArgs(editing, document4) {
|
|
|
177034
177056
|
// src/files/file-ops.js
|
|
177035
177057
|
init_platform();
|
|
177036
177058
|
init_workspace();
|
|
177037
|
-
async function openFile() {
|
|
177038
|
-
try {
|
|
177039
|
-
if ("showOpenFilePicker" in window) {
|
|
177040
|
-
const [handle2] = await window.showOpenFilePicker({
|
|
177041
|
-
types: [
|
|
177042
|
-
{ description: "Jx Component", accept: { "application/json": [".json"] } },
|
|
177043
|
-
{ description: "Markdown Content", accept: { "text/markdown": [".md"] } }
|
|
177044
|
-
]
|
|
177045
|
-
});
|
|
177046
|
-
const file = await handle2.getFile();
|
|
177047
|
-
const text6 = await file.text();
|
|
177048
|
-
const documentPath = await locateDocument(handle2.name);
|
|
177049
|
-
if (handle2.name.endsWith(".md")) {
|
|
177050
|
-
const { document: document4, frontmatter: frontmatter2 } = await loadMarkdown(text6);
|
|
177051
|
-
openTab({
|
|
177052
|
-
id: handle2.name,
|
|
177053
|
-
documentPath,
|
|
177054
|
-
fileHandle: handle2,
|
|
177055
|
-
document: document4,
|
|
177056
|
-
frontmatter: frontmatter2,
|
|
177057
|
-
sourceFormat: "md"
|
|
177058
|
-
});
|
|
177059
|
-
} else {
|
|
177060
|
-
const document4 = JSON.parse(text6);
|
|
177061
|
-
openTab({ id: handle2.name, documentPath, fileHandle: handle2, document: document4 });
|
|
177062
|
-
}
|
|
177063
|
-
statusMessage(`Opened ${handle2.name}`);
|
|
177064
|
-
} else {
|
|
177065
|
-
const input = document.createElement("input");
|
|
177066
|
-
input.type = "file";
|
|
177067
|
-
input.accept = ".json,.md";
|
|
177068
|
-
input.onchange = async () => {
|
|
177069
|
-
const file = input.files?.[0];
|
|
177070
|
-
if (!file)
|
|
177071
|
-
return;
|
|
177072
|
-
const text6 = await file.text();
|
|
177073
|
-
if (file.name.endsWith(".md")) {
|
|
177074
|
-
const { document: document4, frontmatter: frontmatter2 } = await loadMarkdown(text6);
|
|
177075
|
-
openTab({ id: file.name, document: document4, frontmatter: frontmatter2, sourceFormat: "md" });
|
|
177076
|
-
} else {
|
|
177077
|
-
const document4 = JSON.parse(text6);
|
|
177078
|
-
openTab({ id: file.name, document: document4 });
|
|
177079
|
-
}
|
|
177080
|
-
statusMessage(`Opened ${file.name}`);
|
|
177081
|
-
};
|
|
177082
|
-
input.click();
|
|
177083
|
-
}
|
|
177084
|
-
} catch (e) {
|
|
177085
|
-
if (e.name !== "AbortError")
|
|
177086
|
-
statusMessage(`Error: ${e.message}`);
|
|
177087
|
-
}
|
|
177088
|
-
}
|
|
177089
177059
|
async function loadMarkdown(source) {
|
|
177090
177060
|
const { transpileJxMarkdown: transpileJxMarkdown2 } = await Promise.resolve().then(() => (init_transpile(), exports_transpile));
|
|
177091
177061
|
const doc = transpileJxMarkdown2(source);
|
|
@@ -178841,23 +178811,6 @@ async function renderCanvasLive(gen, doc, canvasEl) {
|
|
|
178841
178811
|
} else {
|
|
178842
178812
|
canvasEl.removeAttribute("data-content-mode");
|
|
178843
178813
|
}
|
|
178844
|
-
const platform3 = globalThis.__jxPlatform;
|
|
178845
|
-
if (platform3?.resolveAssetUrl && docBase) {
|
|
178846
|
-
const mediaEls = el.querySelectorAll("img[src], video[src], source[src], video[poster]");
|
|
178847
|
-
for (const node2 of mediaEls) {
|
|
178848
|
-
for (const attr of ["src", "poster"]) {
|
|
178849
|
-
const val = node2.getAttribute(attr);
|
|
178850
|
-
if (val && !val.startsWith("data:") && !val.startsWith("blob:") && !val.startsWith("http")) {
|
|
178851
|
-
try {
|
|
178852
|
-
const resolved = new URL(val, docBase).pathname.replace(/^\//, "");
|
|
178853
|
-
const dataUrl = await platform3.resolveAssetUrl(resolved);
|
|
178854
|
-
if (dataUrl)
|
|
178855
|
-
node2.setAttribute(attr, dataUrl);
|
|
178856
|
-
} catch {}
|
|
178857
|
-
}
|
|
178858
|
-
}
|
|
178859
|
-
}
|
|
178860
|
-
}
|
|
178861
178814
|
canvasEl.appendChild(el);
|
|
178862
178815
|
if (canvasMode === "design" || canvasMode === "edit") {
|
|
178863
178816
|
requestAnimationFrame(() => {
|
|
@@ -183083,38 +183036,40 @@ function registerPanelEvents(panel) {
|
|
|
183083
183036
|
const tab = activeTab.value;
|
|
183084
183037
|
const canvasMode = _ctx8.getCanvasMode();
|
|
183085
183038
|
const elements = withPanelPointerEvents(() => document.elementsFromPoint(e.clientX, e.clientY));
|
|
183039
|
+
if (!tab)
|
|
183040
|
+
return;
|
|
183086
183041
|
for (const el of elements) {
|
|
183087
183042
|
if (canvas.contains(el) && el !== canvas) {
|
|
183088
183043
|
if (layoutElements.has(el)) {
|
|
183089
183044
|
view.layoutSelection = { el, layoutPath: activeLayoutPath };
|
|
183090
|
-
|
|
183045
|
+
tab.session.selection = null;
|
|
183091
183046
|
renderOnly("rightPanel");
|
|
183092
183047
|
return;
|
|
183093
183048
|
}
|
|
183094
183049
|
view.layoutSelection = null;
|
|
183095
183050
|
const originalPath = elToPath.get(el);
|
|
183096
183051
|
if (originalPath) {
|
|
183097
|
-
let path2 = bubbleInlinePath(tab
|
|
183052
|
+
let path2 = bubbleInlinePath(tab.doc.document, originalPath);
|
|
183098
183053
|
const newMedia = mediaName === "base" ? null : mediaName ?? null;
|
|
183099
183054
|
const resolvedEl = path2 === originalPath ? el : findCanvasElement(path2, canvas) || el;
|
|
183100
|
-
if (pathsEqual(path2, tab
|
|
183101
|
-
|
|
183055
|
+
if (pathsEqual(path2, tab.session.selection) && isEditableBlock(resolvedEl) && (canvasMode === "edit" || tab.doc.mode === "content")) {
|
|
183056
|
+
tab.session.ui.activeMedia = newMedia;
|
|
183102
183057
|
_ctx8.enterInlineEdit(resolvedEl, path2);
|
|
183103
183058
|
return;
|
|
183104
183059
|
}
|
|
183105
|
-
if (canvasMode === "design" && tab
|
|
183060
|
+
if (canvasMode === "design" && tab.doc.mode !== "content") {
|
|
183106
183061
|
updateUi("pendingInlineEdit", { path: path2, mediaName });
|
|
183107
|
-
|
|
183108
|
-
|
|
183062
|
+
tab.session.ui.activeMedia = newMedia;
|
|
183063
|
+
tab.session.selection = path2;
|
|
183109
183064
|
return;
|
|
183110
183065
|
}
|
|
183111
|
-
|
|
183112
|
-
|
|
183066
|
+
tab.session.ui.activeMedia = newMedia;
|
|
183067
|
+
tab.session.selection = path2;
|
|
183113
183068
|
return;
|
|
183114
183069
|
}
|
|
183115
183070
|
}
|
|
183116
183071
|
}
|
|
183117
|
-
|
|
183072
|
+
tab.session.selection = null;
|
|
183118
183073
|
}, opts);
|
|
183119
183074
|
overlayClk.addEventListener("dblclick", (e) => {
|
|
183120
183075
|
const barInner = view.blockActionBarEl?.firstElementChild;
|
|
@@ -183128,16 +183083,18 @@ function registerPanelEvents(panel) {
|
|
|
183128
183083
|
return;
|
|
183129
183084
|
const tab = activeTab.value;
|
|
183130
183085
|
const elements = withPanelPointerEvents(() => document.elementsFromPoint(e.clientX, e.clientY));
|
|
183086
|
+
if (!tab)
|
|
183087
|
+
return;
|
|
183131
183088
|
for (const el of elements) {
|
|
183132
183089
|
if (canvas.contains(el) && el !== canvas) {
|
|
183133
183090
|
const originalPath = elToPath.get(el);
|
|
183134
183091
|
if (originalPath) {
|
|
183135
|
-
const path2 = bubbleInlinePath(tab
|
|
183092
|
+
const path2 = bubbleInlinePath(tab.doc.document, originalPath);
|
|
183136
183093
|
const resolvedEl = path2 === originalPath ? el : findCanvasElement(path2, canvas) || el;
|
|
183137
183094
|
if (isEditableBlock(resolvedEl)) {
|
|
183138
183095
|
const newMedia = mediaName === "base" ? null : mediaName ?? null;
|
|
183139
|
-
|
|
183140
|
-
|
|
183096
|
+
tab.session.ui.activeMedia = newMedia;
|
|
183097
|
+
tab.session.selection = path2;
|
|
183141
183098
|
_ctx8.enterInlineEdit(resolvedEl, path2);
|
|
183142
183099
|
return;
|
|
183143
183100
|
}
|
|
@@ -183174,18 +183131,20 @@ function registerPanelEvents(panel) {
|
|
|
183174
183131
|
return;
|
|
183175
183132
|
}
|
|
183176
183133
|
const tab = activeTab.value;
|
|
183134
|
+
if (!tab)
|
|
183135
|
+
return;
|
|
183177
183136
|
const el = withPanelPointerEvents(() => document.elementFromPoint(e.clientX, e.clientY));
|
|
183178
183137
|
if (el && canvas.contains(el) && el !== canvas) {
|
|
183179
183138
|
let path2 = elToPath.get(el);
|
|
183180
183139
|
if (path2) {
|
|
183181
|
-
path2 = bubbleInlinePath(tab
|
|
183182
|
-
if (!pathsEqual(path2, tab
|
|
183183
|
-
|
|
183140
|
+
path2 = bubbleInlinePath(tab.doc.document, path2);
|
|
183141
|
+
if (!pathsEqual(path2, tab.session.hover)) {
|
|
183142
|
+
tab.session.hover = path2;
|
|
183184
183143
|
renderOnly("overlays");
|
|
183185
183144
|
}
|
|
183186
183145
|
}
|
|
183187
|
-
} else if (tab
|
|
183188
|
-
|
|
183146
|
+
} else if (tab.session.hover) {
|
|
183147
|
+
tab.session.hover = null;
|
|
183189
183148
|
renderOnly("overlays");
|
|
183190
183149
|
}
|
|
183191
183150
|
}, opts);
|
|
@@ -183388,6 +183347,19 @@ function extOf(name) {
|
|
|
183388
183347
|
const dot = name.lastIndexOf(".");
|
|
183389
183348
|
return dot > 0 ? name.slice(dot).toLowerCase() : "";
|
|
183390
183349
|
}
|
|
183350
|
+
var IMAGE_EXTENSIONS2 = new Set([
|
|
183351
|
+
".jpg",
|
|
183352
|
+
".jpeg",
|
|
183353
|
+
".png",
|
|
183354
|
+
".gif",
|
|
183355
|
+
".svg",
|
|
183356
|
+
".webp",
|
|
183357
|
+
".avif",
|
|
183358
|
+
".ico"
|
|
183359
|
+
]);
|
|
183360
|
+
function isImage(ext) {
|
|
183361
|
+
return IMAGE_EXTENSIONS2.has(ext);
|
|
183362
|
+
}
|
|
183391
183363
|
function categoryFor(dir, ext) {
|
|
183392
183364
|
if (ext && MEDIA_EXTENSIONS2.has(ext))
|
|
183393
183365
|
return "Media";
|
|
@@ -183645,9 +183617,12 @@ async function renderBrowse(container, ctx) {
|
|
|
183645
183617
|
<sp-table-row
|
|
183646
183618
|
value=${f.path}
|
|
183647
183619
|
class="browse-row"
|
|
183648
|
-
|
|
183620
|
+
style=${isImage(f.ext) ? "cursor:default" : ""}
|
|
183621
|
+
@click=${isImage(f.ext) ? nothing : () => ctx.openFile(f.path)}
|
|
183649
183622
|
>
|
|
183650
|
-
<sp-table-cell class="browse-name-cell"
|
|
183623
|
+
<sp-table-cell class="browse-name-cell"
|
|
183624
|
+
>${isImage(f.ext) ? html`<img class="browse-thumb" src="/${f.path}" />` : nothing}${f.name}</sp-table-cell
|
|
183625
|
+
>
|
|
183651
183626
|
<sp-table-cell>${f.category}</sp-table-cell>
|
|
183652
183627
|
<sp-table-cell>${f.type}</sp-table-cell>
|
|
183653
183628
|
<sp-table-cell class="browse-path-cell">${f.path}</sp-table-cell>
|
|
@@ -184338,6 +184313,48 @@ init_store();
|
|
|
184338
184313
|
init_platform();
|
|
184339
184314
|
init_components();
|
|
184340
184315
|
init_workspace();
|
|
184316
|
+
|
|
184317
|
+
// src/recent-projects.js
|
|
184318
|
+
var STORAGE_KEY = "jx-studio-recent-projects";
|
|
184319
|
+
var FILES_STORAGE_KEY = "jx-studio-recent-files";
|
|
184320
|
+
var MAX_RECENT = 8;
|
|
184321
|
+
var MAX_RECENT_FILES = 10;
|
|
184322
|
+
function getRecentProjects() {
|
|
184323
|
+
try {
|
|
184324
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
184325
|
+
if (!raw)
|
|
184326
|
+
return [];
|
|
184327
|
+
return JSON.parse(raw).sort((a, b) => b.timestamp - a.timestamp);
|
|
184328
|
+
} catch {
|
|
184329
|
+
return [];
|
|
184330
|
+
}
|
|
184331
|
+
}
|
|
184332
|
+
function addRecentProject(name, root2) {
|
|
184333
|
+
const projects = getRecentProjects().filter((p) => p.root !== root2);
|
|
184334
|
+
projects.unshift({ name, root: root2, timestamp: Date.now() });
|
|
184335
|
+
if (projects.length > MAX_RECENT)
|
|
184336
|
+
projects.length = MAX_RECENT;
|
|
184337
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(projects));
|
|
184338
|
+
}
|
|
184339
|
+
function getRecentFiles() {
|
|
184340
|
+
try {
|
|
184341
|
+
const raw = localStorage.getItem(FILES_STORAGE_KEY);
|
|
184342
|
+
if (!raw)
|
|
184343
|
+
return [];
|
|
184344
|
+
return JSON.parse(raw).sort((a, b) => b.timestamp - a.timestamp);
|
|
184345
|
+
} catch {
|
|
184346
|
+
return [];
|
|
184347
|
+
}
|
|
184348
|
+
}
|
|
184349
|
+
function trackRecentFile(file) {
|
|
184350
|
+
const recent = getRecentFiles().filter((f) => f.path !== file.path);
|
|
184351
|
+
recent.unshift({ path: file.path, name: file.name, timestamp: Date.now() });
|
|
184352
|
+
if (recent.length > MAX_RECENT_FILES)
|
|
184353
|
+
recent.length = MAX_RECENT_FILES;
|
|
184354
|
+
localStorage.setItem(FILES_STORAGE_KEY, JSON.stringify(recent));
|
|
184355
|
+
}
|
|
184356
|
+
|
|
184357
|
+
// src/files/files.js
|
|
184341
184358
|
var fileIconMap = {
|
|
184342
184359
|
"sp-icon-folder-open": html`<sp-icon-folder-open></sp-icon-folder-open>`,
|
|
184343
184360
|
"sp-icon-folder": html`<sp-icon-folder></sp-icon-folder>`,
|
|
@@ -184389,6 +184406,7 @@ async function openProject({ renderActivityBar, renderLeftPanel }) {
|
|
|
184389
184406
|
if (!result)
|
|
184390
184407
|
return;
|
|
184391
184408
|
const { config, handle: handle2 } = result;
|
|
184409
|
+
replaceAllTabs({ id: "initial", document: { tagName: "div", children: [] } });
|
|
184392
184410
|
setProjectState({
|
|
184393
184411
|
...projectState,
|
|
184394
184412
|
projectRoot: handle2.root,
|
|
@@ -184422,6 +184440,7 @@ async function openProject({ renderActivityBar, renderLeftPanel }) {
|
|
|
184422
184440
|
}
|
|
184423
184441
|
projectState.projectDirs = foundDirs;
|
|
184424
184442
|
view.leftTab = "files";
|
|
184443
|
+
addRecentProject(projectState.name, projectState.projectRoot);
|
|
184425
184444
|
renderActivityBar();
|
|
184426
184445
|
renderLeftPanel();
|
|
184427
184446
|
statusMessage(`Opened project: ${projectState.name}`);
|
|
@@ -184790,6 +184809,7 @@ async function openFileInTab(path2) {
|
|
|
184790
184809
|
sourceFormat: path2.endsWith(".md") ? "md" : null
|
|
184791
184810
|
});
|
|
184792
184811
|
projectState.selectedPath = path2;
|
|
184812
|
+
trackRecentFile({ path: path2, name: path2.split("/").pop() || path2 });
|
|
184793
184813
|
statusMessage(`Opened ${path2.split("/").pop()}`);
|
|
184794
184814
|
} catch (e) {
|
|
184795
184815
|
statusMessage(`Error: ${e.message}`);
|
|
@@ -185753,6 +185773,16 @@ function createDevServerPlatform() {
|
|
|
185753
185773
|
} catch {}
|
|
185754
185774
|
return null;
|
|
185755
185775
|
},
|
|
185776
|
+
async searchFiles(query) {
|
|
185777
|
+
const glob = `**/*${query}*.{json,md}`;
|
|
185778
|
+
const res = await fetch(`/__studio/files?dir=${encodeURIComponent(serverPath("."))}&glob=${encodeURIComponent(glob)}`);
|
|
185779
|
+
if (!res.ok)
|
|
185780
|
+
return [];
|
|
185781
|
+
const entries2 = await res.json();
|
|
185782
|
+
for (const e of entries2)
|
|
185783
|
+
e.path = stripRoot(e.path);
|
|
185784
|
+
return entries2;
|
|
185785
|
+
},
|
|
185756
185786
|
async fetchPluginSchema(src, prototype, base2) {
|
|
185757
185787
|
const params = new URLSearchParams({ src });
|
|
185758
185788
|
if (prototype)
|
|
@@ -210014,6 +210044,67 @@ class IconRemove extends IconBase {
|
|
|
210014
210044
|
}
|
|
210015
210045
|
}
|
|
210016
210046
|
|
|
210047
|
+
// ../../node_modules/@spectrum-web-components/icons-workflow/src/elements/IconFullScreen.js
|
|
210048
|
+
init_index_dev();
|
|
210049
|
+
|
|
210050
|
+
// ../../node_modules/@spectrum-web-components/icons-workflow/src/icons-s2/FullScreen.js
|
|
210051
|
+
var FullScreenIcon = ({ width: l = 24, height: r8 = 24, hidden: t15 = false, title: c6 = "Full Screen" } = {}) => tag6`<svg
|
|
210052
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
210053
|
+
width="${l}"
|
|
210054
|
+
height="${r8}"
|
|
210055
|
+
viewBox="0 0 20 20"
|
|
210056
|
+
aria-hidden=${t15 ? "true" : "false"}
|
|
210057
|
+
role="img"
|
|
210058
|
+
fill="currentColor"
|
|
210059
|
+
aria-label="${c6}"
|
|
210060
|
+
>
|
|
210061
|
+
<path
|
|
210062
|
+
d="M12.75,14.93652h-5.5c-1.24072,0-2.25-1.00928-2.25-2.25v-5.5c0-1.24072,1.00928-2.25,2.25-2.25h5.5c1.24072,0,2.25,1.00928,2.25,2.25v5.5c0,1.24072-1.00928,2.25-2.25,2.25ZM7.25,6.43652c-.41357,0-.75.33643-.75.75v5.5c0,.41357.33643.75.75.75h5.5c.41357,0,.75-.33643.75-.75v-5.5c0-.41357-.33643-.75-.75-.75h-5.5Z"
|
|
210063
|
+
fill="currentColor"
|
|
210064
|
+
/>
|
|
210065
|
+
<path
|
|
210066
|
+
d="M4.5,19h-2.25c-.68945,0-1.25-.56055-1.25-1.25v-2.25c0-.41406.33594-.75.75-.75s.75.33594.75.75v2h2c.41406,0,.75.33594.75.75s-.33594.75-.75.75Z"
|
|
210067
|
+
fill="currentColor"
|
|
210068
|
+
/>
|
|
210069
|
+
<path
|
|
210070
|
+
d="M17.75,19h-2.25c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2v-2c0-.41406.33594-.75.75-.75s.75.33594.75.75v2.25c0,.68945-.56055,1.25-1.25,1.25Z"
|
|
210071
|
+
fill="currentColor"
|
|
210072
|
+
stroke-width="0"
|
|
210073
|
+
/>
|
|
210074
|
+
<path
|
|
210075
|
+
d="M18.25,5.25c-.41406,0-.75-.33594-.75-.75v-2h-2c-.41406,0-.75-.33594-.75-.75s.33594-.75.75-.75h2.25c.68945,0,1.25.56055,1.25,1.25v2.25c0,.41406-.33594.75-.75.75ZM17.75,2.5h.00977-.00977Z"
|
|
210076
|
+
fill="currentColor"
|
|
210077
|
+
/>
|
|
210078
|
+
<path
|
|
210079
|
+
d="M1.75,5.25c-.41406,0-.75-.33594-.75-.75v-2.25c0-.68945.56055-1.25,1.25-1.25h2.25c.41406,0,.75.33594.75.75s-.33594.75-.75.75h-2v2c0,.41406-.33594.75-.75.75Z"
|
|
210080
|
+
fill="currentColor"
|
|
210081
|
+
/>
|
|
210082
|
+
</svg>`;
|
|
210083
|
+
|
|
210084
|
+
// ../../node_modules/@spectrum-web-components/icons-workflow/src/icons/FullScreen.js
|
|
210085
|
+
var FullScreenIcon2 = ({ width: a5 = 24, height: e20 = 24, hidden: t15 = false, title: r8 = "Full Screen" } = {}) => tag6`<svg
|
|
210086
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
210087
|
+
height="${e20}"
|
|
210088
|
+
viewBox="0 0 36 36"
|
|
210089
|
+
width="${a5}"
|
|
210090
|
+
aria-hidden=${t15 ? "true" : "false"}
|
|
210091
|
+
role="img"
|
|
210092
|
+
fill="currentColor"
|
|
210093
|
+
aria-label="${r8}"
|
|
210094
|
+
>
|
|
210095
|
+
<path
|
|
210096
|
+
d="M32 24.5V30h-5.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5H34v-7.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5ZM4 30v-5.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5V32h7.5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5ZM26 4.5v1a.5.5 0 0 0 .5.5H32v5.5a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5V4h-7.5a.5.5 0 0 0-.5.5ZM4 6h5.5a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5H2v7.5a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5Z"
|
|
210097
|
+
/>
|
|
210098
|
+
<rect height="16" rx=".5" ry=".5" width="20" x="8" y="10" />
|
|
210099
|
+
</svg>`;
|
|
210100
|
+
|
|
210101
|
+
// ../../node_modules/@spectrum-web-components/icons-workflow/src/elements/IconFullScreen.js
|
|
210102
|
+
class IconFullScreen extends IconBase {
|
|
210103
|
+
render() {
|
|
210104
|
+
return setCustomTemplateLiteralTag2(html8), this.spectrumVersion === 2 ? FullScreenIcon({ hidden: !this.label, title: this.label }) : FullScreenIcon2({ hidden: !this.label, title: this.label });
|
|
210105
|
+
}
|
|
210106
|
+
}
|
|
210107
|
+
|
|
210017
210108
|
// ../../node_modules/@spectrum-web-components/icons-workflow/src/elements/IconViewColumn.js
|
|
210018
210109
|
init_index_dev();
|
|
210019
210110
|
|
|
@@ -211139,6 +211230,7 @@ var components = [
|
|
|
211139
211230
|
["sp-icon-text-baseline-shift", IconTextBaselineShift],
|
|
211140
211231
|
["sp-icon-flip-vertical", IconFlipVertical],
|
|
211141
211232
|
["sp-icon-remove", IconRemove],
|
|
211233
|
+
["sp-icon-full-screen", IconFullScreen],
|
|
211142
211234
|
["sp-icon-download", IconDownload],
|
|
211143
211235
|
["sp-icon-checkmark", IconCheckmark],
|
|
211144
211236
|
["sp-icon-view-column", IconViewColumn],
|
|
@@ -211167,14 +211259,14 @@ Theme.registerThemeFragment("dark", "color", theme_dark_css_default);
|
|
|
211167
211259
|
Theme.registerThemeFragment("medium", "scale", scale_medium_css_default);
|
|
211168
211260
|
|
|
211169
211261
|
// src/ui/panel-resize.js
|
|
211170
|
-
var
|
|
211262
|
+
var STORAGE_KEY2 = "jx-studio-panel-widths";
|
|
211171
211263
|
var MIN_WIDTH = 160;
|
|
211172
211264
|
var MAX_RATIO = 0.5;
|
|
211173
211265
|
var DEFAULT_LEFT = 240;
|
|
211174
211266
|
var DEFAULT_RIGHT = 280;
|
|
211175
211267
|
var root2 = document.documentElement;
|
|
211176
211268
|
try {
|
|
211177
|
-
const saved = JSON.parse(localStorage.getItem(
|
|
211269
|
+
const saved = JSON.parse(localStorage.getItem(STORAGE_KEY2) || "{}");
|
|
211178
211270
|
if (saved.left)
|
|
211179
211271
|
root2.style.setProperty("--panel-w-left", `${saved.left}px`);
|
|
211180
211272
|
if (saved.right)
|
|
@@ -211220,7 +211312,7 @@ function persistWidths() {
|
|
|
211220
211312
|
const left = parseInt(getComputedStyle(root2).getPropertyValue("--panel-w-left")) || DEFAULT_LEFT;
|
|
211221
211313
|
const right = parseInt(getComputedStyle(root2).getPropertyValue("--panel-w-right")) || DEFAULT_RIGHT;
|
|
211222
211314
|
try {
|
|
211223
|
-
localStorage.setItem(
|
|
211315
|
+
localStorage.setItem(STORAGE_KEY2, JSON.stringify({ left, right }));
|
|
211224
211316
|
} catch {}
|
|
211225
211317
|
}
|
|
211226
211318
|
var resizeLeft = document.getElementById("resize-left");
|
|
@@ -211233,11 +211325,162 @@ if (resizeRight)
|
|
|
211233
211325
|
// src/editor/shortcuts.js
|
|
211234
211326
|
init_store();
|
|
211235
211327
|
init_workspace();
|
|
211328
|
+
|
|
211329
|
+
// src/panels/quick-search.js
|
|
211330
|
+
init_platform();
|
|
211331
|
+
var _open = false;
|
|
211332
|
+
var _query = "";
|
|
211333
|
+
var _results = [];
|
|
211334
|
+
var _selectedIndex = 0;
|
|
211335
|
+
var _debounceTimer = 0;
|
|
211336
|
+
var _container = null;
|
|
211337
|
+
function initQuickSearch() {
|
|
211338
|
+
_container = document.createElement("div");
|
|
211339
|
+
_container.style.display = "contents";
|
|
211340
|
+
(document.querySelector("sp-theme") || document.body).appendChild(_container);
|
|
211341
|
+
}
|
|
211342
|
+
function openQuickSearch() {
|
|
211343
|
+
_open = true;
|
|
211344
|
+
_query = "";
|
|
211345
|
+
_results = [];
|
|
211346
|
+
_selectedIndex = 0;
|
|
211347
|
+
renderOverlay();
|
|
211348
|
+
requestAnimationFrame(() => {
|
|
211349
|
+
const input = _container?.querySelector(".quick-search-input");
|
|
211350
|
+
if (input)
|
|
211351
|
+
input.focus();
|
|
211352
|
+
});
|
|
211353
|
+
}
|
|
211354
|
+
function closeQuickSearch() {
|
|
211355
|
+
_open = false;
|
|
211356
|
+
renderOverlay();
|
|
211357
|
+
}
|
|
211358
|
+
async function doSearch(query3) {
|
|
211359
|
+
if (!query3.trim()) {
|
|
211360
|
+
_results = [];
|
|
211361
|
+
_selectedIndex = 0;
|
|
211362
|
+
renderOverlay();
|
|
211363
|
+
return;
|
|
211364
|
+
}
|
|
211365
|
+
try {
|
|
211366
|
+
const platform4 = getPlatform();
|
|
211367
|
+
_results = await platform4.searchFiles(query3.trim().toLowerCase());
|
|
211368
|
+
_selectedIndex = 0;
|
|
211369
|
+
renderOverlay();
|
|
211370
|
+
} catch {
|
|
211371
|
+
_results = [];
|
|
211372
|
+
renderOverlay();
|
|
211373
|
+
}
|
|
211374
|
+
}
|
|
211375
|
+
function onInput(e20) {
|
|
211376
|
+
_query = e20.target.value;
|
|
211377
|
+
clearTimeout(_debounceTimer);
|
|
211378
|
+
_debounceTimer = setTimeout(() => doSearch(_query), 150);
|
|
211379
|
+
renderOverlay();
|
|
211380
|
+
}
|
|
211381
|
+
function onKeydown2(e20) {
|
|
211382
|
+
const items = _query.trim() ? _results : getRecentFiles();
|
|
211383
|
+
switch (e20.key) {
|
|
211384
|
+
case "ArrowDown":
|
|
211385
|
+
e20.preventDefault();
|
|
211386
|
+
_selectedIndex = Math.min(_selectedIndex + 1, items.length - 1);
|
|
211387
|
+
renderOverlay();
|
|
211388
|
+
break;
|
|
211389
|
+
case "ArrowUp":
|
|
211390
|
+
e20.preventDefault();
|
|
211391
|
+
_selectedIndex = Math.max(_selectedIndex - 1, 0);
|
|
211392
|
+
renderOverlay();
|
|
211393
|
+
break;
|
|
211394
|
+
case "Enter":
|
|
211395
|
+
e20.preventDefault();
|
|
211396
|
+
if (items[_selectedIndex])
|
|
211397
|
+
selectItem(items[_selectedIndex]);
|
|
211398
|
+
break;
|
|
211399
|
+
case "Escape":
|
|
211400
|
+
e20.preventDefault();
|
|
211401
|
+
closeQuickSearch();
|
|
211402
|
+
break;
|
|
211403
|
+
}
|
|
211404
|
+
}
|
|
211405
|
+
function selectItem(item) {
|
|
211406
|
+
closeQuickSearch();
|
|
211407
|
+
const path2 = item.path;
|
|
211408
|
+
trackRecentFile({ path: path2, name: path2.split("/").pop() });
|
|
211409
|
+
openFileInTab(path2);
|
|
211410
|
+
}
|
|
211411
|
+
function fileIcon(name) {
|
|
211412
|
+
const ext = name.split(".").pop()?.toLowerCase();
|
|
211413
|
+
switch (ext) {
|
|
211414
|
+
case "json":
|
|
211415
|
+
return html`<sp-icon-file-code size="s"></sp-icon-file-code>`;
|
|
211416
|
+
case "md":
|
|
211417
|
+
return html`<sp-icon-file-txt size="s"></sp-icon-file-txt>`;
|
|
211418
|
+
default:
|
|
211419
|
+
return html`<sp-icon-document size="s"></sp-icon-document>`;
|
|
211420
|
+
}
|
|
211421
|
+
}
|
|
211422
|
+
function dirPart(path2) {
|
|
211423
|
+
const parts = path2.split("/");
|
|
211424
|
+
parts.pop();
|
|
211425
|
+
return parts.length ? parts.join("/") : "";
|
|
211426
|
+
}
|
|
211427
|
+
function renderOverlay() {
|
|
211428
|
+
if (!_container)
|
|
211429
|
+
return;
|
|
211430
|
+
if (!_open) {
|
|
211431
|
+
render2(nothing, _container);
|
|
211432
|
+
return;
|
|
211433
|
+
}
|
|
211434
|
+
const recentFiles = getRecentFiles();
|
|
211435
|
+
const showRecent = !_query.trim();
|
|
211436
|
+
const items = showRecent ? recentFiles : _results;
|
|
211437
|
+
const tpl = html`
|
|
211438
|
+
<div class="quick-search-overlay" @click=${closeQuickSearch}>
|
|
211439
|
+
<div class="quick-search-panel" @click=${(e20) => e20.stopPropagation()}>
|
|
211440
|
+
<input
|
|
211441
|
+
class="quick-search-input"
|
|
211442
|
+
type="text"
|
|
211443
|
+
placeholder="Search project files…"
|
|
211444
|
+
.value=${_query}
|
|
211445
|
+
@input=${onInput}
|
|
211446
|
+
@keydown=${onKeydown2}
|
|
211447
|
+
/>
|
|
211448
|
+
<div class="quick-search-results">
|
|
211449
|
+
${items.length === 0 && _query.trim() ? html`<div class="quick-search-empty">No results</div>` : nothing}
|
|
211450
|
+
${items.length === 0 && !_query.trim() && recentFiles.length === 0 ? html`<div class="quick-search-empty">Type to search project files</div>` : nothing}
|
|
211451
|
+
${showRecent && recentFiles.length ? html`<div class="quick-search-section-label">Recently opened</div>` : nothing}
|
|
211452
|
+
${items.map((item, i6) => html`
|
|
211453
|
+
<div
|
|
211454
|
+
class="quick-search-item ${i6 === _selectedIndex ? "selected" : ""}"
|
|
211455
|
+
@click=${() => selectItem(item)}
|
|
211456
|
+
@mouseenter=${() => {
|
|
211457
|
+
_selectedIndex = i6;
|
|
211458
|
+
renderOverlay();
|
|
211459
|
+
}}
|
|
211460
|
+
>
|
|
211461
|
+
<span class="quick-search-icon"
|
|
211462
|
+
>${fileIcon(item.name || item.path.split("/").pop())}</span
|
|
211463
|
+
>
|
|
211464
|
+
<span class="quick-search-name">${item.name || item.path.split("/").pop()}</span>
|
|
211465
|
+
<span class="quick-search-path">${dirPart(item.path)}</span>
|
|
211466
|
+
${showRecent ? html`<span class="quick-search-badge">recent</span>` : nothing}
|
|
211467
|
+
</div>
|
|
211468
|
+
`)}
|
|
211469
|
+
</div>
|
|
211470
|
+
</div>
|
|
211471
|
+
</div>
|
|
211472
|
+
`;
|
|
211473
|
+
render2(tpl, _container);
|
|
211474
|
+
}
|
|
211475
|
+
|
|
211476
|
+
// src/editor/shortcuts.js
|
|
211236
211477
|
function initShortcuts(getContext) {
|
|
211237
211478
|
canvasWrap.addEventListener("wheel", (e20) => {
|
|
211238
211479
|
const { canvasMode, panX, panY, setPan, applyTransform: applyTransform2 } = getContext();
|
|
211239
211480
|
if (canvasMode === "edit")
|
|
211240
211481
|
return;
|
|
211482
|
+
if (canvasMode === "manage")
|
|
211483
|
+
return;
|
|
211241
211484
|
e20.preventDefault();
|
|
211242
211485
|
if (e20.ctrlKey || e20.metaKey) {
|
|
211243
211486
|
const rect = canvasWrap.getBoundingClientRect();
|
|
@@ -211341,6 +211584,10 @@ function initShortcuts(getContext) {
|
|
|
211341
211584
|
e20.preventDefault();
|
|
211342
211585
|
openProject2();
|
|
211343
211586
|
break;
|
|
211587
|
+
case "p":
|
|
211588
|
+
e20.preventDefault();
|
|
211589
|
+
openQuickSearch();
|
|
211590
|
+
break;
|
|
211344
211591
|
case "s":
|
|
211345
211592
|
e20.preventDefault();
|
|
211346
211593
|
saveFile2();
|
|
@@ -211596,6 +211843,9 @@ function tbBtnTpl(label4, onClick, iconTag) {
|
|
|
211596
211843
|
function mount5(rootEl, ctx) {
|
|
211597
211844
|
_rootEl = rootEl;
|
|
211598
211845
|
_ctx11 = ctx;
|
|
211846
|
+
if (globalThis.__jxPlatform?.windowControls) {
|
|
211847
|
+
rootEl.classList.add("electrobun-webkit-app-region-drag");
|
|
211848
|
+
}
|
|
211599
211849
|
_scope4 = effectScope();
|
|
211600
211850
|
_scope4.run(() => {
|
|
211601
211851
|
effect(() => {
|
|
@@ -211732,10 +211982,52 @@ function toolbarTemplate() {
|
|
|
211732
211982
|
`)}
|
|
211733
211983
|
</sp-action-group>
|
|
211734
211984
|
`;
|
|
211985
|
+
const windowControls = globalThis.__jxPlatform?.windowControls;
|
|
211986
|
+
const csdTpl = windowControls ? html`
|
|
211987
|
+
<sp-action-group class="window-controls" size="s">
|
|
211988
|
+
<sp-action-button
|
|
211989
|
+
quiet
|
|
211990
|
+
size="s"
|
|
211991
|
+
title="Minimize"
|
|
211992
|
+
@click=${() => windowControls.minimize()}
|
|
211993
|
+
>
|
|
211994
|
+
<sp-icon-remove slot="icon"></sp-icon-remove>
|
|
211995
|
+
</sp-action-button>
|
|
211996
|
+
<sp-action-button
|
|
211997
|
+
quiet
|
|
211998
|
+
size="s"
|
|
211999
|
+
title="Maximize"
|
|
212000
|
+
@click=${() => windowControls.maximize()}
|
|
212001
|
+
>
|
|
212002
|
+
<sp-icon-full-screen slot="icon"></sp-icon-full-screen>
|
|
212003
|
+
</sp-action-button>
|
|
212004
|
+
<sp-action-button
|
|
212005
|
+
quiet
|
|
212006
|
+
size="s"
|
|
212007
|
+
title="Close"
|
|
212008
|
+
class="csd-close"
|
|
212009
|
+
@click=${() => windowControls.close()}
|
|
212010
|
+
>
|
|
212011
|
+
<sp-icon-close slot="icon"></sp-icon-close>
|
|
212012
|
+
</sp-action-button>
|
|
212013
|
+
</sp-action-group>
|
|
212014
|
+
` : nothing;
|
|
212015
|
+
const recentProjects = getRecentProjects();
|
|
212016
|
+
const recentProjectsTpl = recentProjects.length ? html`
|
|
212017
|
+
<overlay-trigger placement="bottom-start">
|
|
212018
|
+
<sp-action-button size="s" slot="trigger" title="Recent projects">
|
|
212019
|
+
<sp-icon-chevron-down slot="icon"></sp-icon-chevron-down>
|
|
212020
|
+
</sp-action-button>
|
|
212021
|
+
<sp-popover slot="click-content" tip>
|
|
212022
|
+
<sp-menu @change=${(e20) => _ctx11.openRecentProject(e20.target.value)}>
|
|
212023
|
+
${recentProjects.map((p2) => html`<sp-menu-item value=${p2.root}>${p2.name}</sp-menu-item>`)}
|
|
212024
|
+
</sp-menu>
|
|
212025
|
+
</sp-popover>
|
|
212026
|
+
</overlay-trigger>
|
|
212027
|
+
` : nothing;
|
|
211735
212028
|
return html`
|
|
211736
212029
|
<sp-action-group compact size="s">
|
|
211737
|
-
${tbBtnTpl("Open Project", _ctx11.openProject, "sp-icon-folder-open")}
|
|
211738
|
-
${tbBtnTpl("Open File", _ctx11.openFile, "sp-icon-document")}
|
|
212030
|
+
${tbBtnTpl("Open Project", _ctx11.openProject, "sp-icon-folder-open")} ${recentProjectsTpl}
|
|
211739
212031
|
${tbBtnTpl("Save", _ctx11.saveFile, "sp-icon-save-floppy")}
|
|
211740
212032
|
</sp-action-group>
|
|
211741
212033
|
<sp-action-group compact size="s">
|
|
@@ -211743,14 +212035,12 @@ function toolbarTemplate() {
|
|
|
211743
212035
|
${tbBtnTpl("Redo", () => redo(activeTab.value), "sp-icon-redo")}
|
|
211744
212036
|
</sp-action-group>
|
|
211745
212037
|
<div class="tb-spacer"></div>
|
|
211746
|
-
|
|
211747
|
-
|
|
211748
|
-
|
|
211749
|
-
|
|
211750
|
-
>` : nothing}
|
|
211751
|
-
${breadcrumbTpl}
|
|
212038
|
+
<sp-action-button class="tb-search-trigger" size="s" quiet @click=${openQuickSearch}>
|
|
212039
|
+
<sp-icon-search slot="icon"></sp-icon-search>
|
|
212040
|
+
<span class="tb-search-label">Search files… <kbd>⌘P</kbd></span>
|
|
212041
|
+
</sp-action-button>
|
|
211752
212042
|
<div class="tb-spacer"></div>
|
|
211753
|
-
${togglesTpl} ${modeSwitcherTpl}
|
|
212043
|
+
${breadcrumbTpl} ${togglesTpl} ${modeSwitcherTpl} ${csdTpl}
|
|
211754
212044
|
`;
|
|
211755
212045
|
}
|
|
211756
212046
|
|
|
@@ -214890,15 +215180,15 @@ function bindableFieldRow(label4, type2, rawValue, onChange, filterFn = null, ex
|
|
|
214890
215180
|
const isBound = typeof rawValue === "object" && rawValue !== null && rawValue.$ref;
|
|
214891
215181
|
const signalDefs = Object.entries(defs).filter(([, d5]) => filterFn ? filterFn(d5) : !d5.$handler && d5.$prototype !== "Function");
|
|
214892
215182
|
let debounce;
|
|
214893
|
-
const
|
|
215183
|
+
const onInput2 = (e20) => {
|
|
214894
215184
|
clearTimeout(debounce);
|
|
214895
215185
|
debounce = setTimeout(() => onChange(e20.target.value), 400);
|
|
214896
215186
|
};
|
|
214897
215187
|
const staticVal = isBound ? "" : rawValue ?? "";
|
|
214898
|
-
const staticTpl = type2 === "textarea" ? html`<sp-textfield multiline size="s" value=${staticVal} @input=${
|
|
215188
|
+
const staticTpl = type2 === "textarea" ? html`<sp-textfield multiline size="s" value=${staticVal} @input=${onInput2}></sp-textfield>` : type2 === "checkbox" ? html`<sp-checkbox
|
|
214899
215189
|
?checked=${!!staticVal}
|
|
214900
215190
|
@change=${(e20) => onChange(e20.target.checked)}
|
|
214901
|
-
></sp-checkbox>` : html`<sp-textfield size="s" value=${staticVal} @input=${
|
|
215191
|
+
></sp-checkbox>` : html`<sp-textfield size="s" value=${staticVal} @input=${onInput2}></sp-textfield>`;
|
|
214902
215192
|
const boundTpl = html`
|
|
214903
215193
|
<sp-picker
|
|
214904
215194
|
size="s"
|
|
@@ -215003,16 +215293,18 @@ function renderFrontmatterOnlyPanel() {
|
|
|
215003
215293
|
fields.push({ field, entry: fieldSchema, value: fm[field] });
|
|
215004
215294
|
}
|
|
215005
215295
|
for (const [field, value2] of Object.entries(fm)) {
|
|
215006
|
-
if (
|
|
215007
|
-
|
|
215008
|
-
|
|
215009
|
-
|
|
215010
|
-
|
|
215011
|
-
|
|
215012
|
-
}
|
|
215296
|
+
if (schemaProps[field] || field.startsWith("$"))
|
|
215297
|
+
continue;
|
|
215298
|
+
fields.push({
|
|
215299
|
+
field,
|
|
215300
|
+
entry: { type: typeof value2 === "boolean" ? "boolean" : "string" },
|
|
215301
|
+
value: value2
|
|
215302
|
+
});
|
|
215013
215303
|
}
|
|
215014
215304
|
} else {
|
|
215015
215305
|
for (const [field, value2] of Object.entries(fm)) {
|
|
215306
|
+
if (field.startsWith("$"))
|
|
215307
|
+
continue;
|
|
215016
215308
|
fields.push({
|
|
215017
215309
|
field,
|
|
215018
215310
|
entry: { type: typeof value2 === "boolean" ? "boolean" : "string" },
|
|
@@ -216094,16 +216386,18 @@ function renderPropertiesPanelTemplate(ctx) {
|
|
|
216094
216386
|
fields.push({ field, entry: fieldSchema, value: fm[field] });
|
|
216095
216387
|
}
|
|
216096
216388
|
for (const [field, value2] of Object.entries(fm)) {
|
|
216097
|
-
if (
|
|
216098
|
-
|
|
216099
|
-
|
|
216100
|
-
|
|
216101
|
-
|
|
216102
|
-
|
|
216103
|
-
}
|
|
216389
|
+
if (schemaProps[field] || field.startsWith("$"))
|
|
216390
|
+
continue;
|
|
216391
|
+
fields.push({
|
|
216392
|
+
field,
|
|
216393
|
+
entry: { type: typeof value2 === "boolean" ? "boolean" : "string" },
|
|
216394
|
+
value: value2
|
|
216395
|
+
});
|
|
216104
216396
|
}
|
|
216105
216397
|
} else {
|
|
216106
216398
|
for (const [field, value2] of Object.entries(fm)) {
|
|
216399
|
+
if (field.startsWith("$"))
|
|
216400
|
+
continue;
|
|
216107
216401
|
fields.push({
|
|
216108
216402
|
field,
|
|
216109
216403
|
entry: { type: typeof value2 === "boolean" ? "boolean" : "string" },
|
|
@@ -217034,7 +217328,7 @@ mount5(toolbarEl, {
|
|
|
217034
217328
|
navigateBack: () => navigateBack(),
|
|
217035
217329
|
closeFunctionEditor: () => closeFunctionEditor(),
|
|
217036
217330
|
openProject: () => openProject2(),
|
|
217037
|
-
|
|
217331
|
+
openRecentProject: (root3) => openRecentProject(root3),
|
|
217038
217332
|
saveFile: () => saveFile(),
|
|
217039
217333
|
parseMediaEntries,
|
|
217040
217334
|
getCanvasMode,
|
|
@@ -217042,6 +217336,7 @@ mount5(toolbarEl, {
|
|
|
217042
217336
|
renderCanvas: () => renderCanvas(),
|
|
217043
217337
|
safeRenderRightPanel: () => safeRenderRightPanel()
|
|
217044
217338
|
});
|
|
217339
|
+
initQuickSearch();
|
|
217045
217340
|
mount8(document.querySelector("#tab-strip"));
|
|
217046
217341
|
mount3({
|
|
217047
217342
|
getCanvasMode,
|
|
@@ -217262,6 +217557,51 @@ function openProject2() {
|
|
|
217262
217557
|
renderLeftPanel
|
|
217263
217558
|
});
|
|
217264
217559
|
}
|
|
217560
|
+
async function openRecentProject(root3) {
|
|
217561
|
+
try {
|
|
217562
|
+
const platform4 = getPlatform();
|
|
217563
|
+
platform4.projectRoot = root3;
|
|
217564
|
+
const content3 = await platform4.readFile("project.json");
|
|
217565
|
+
const config = JSON.parse(content3);
|
|
217566
|
+
replaceAllTabs({ id: "initial", document: { tagName: "div", children: [] } });
|
|
217567
|
+
setProjectState({
|
|
217568
|
+
...projectState,
|
|
217569
|
+
projectRoot: root3,
|
|
217570
|
+
isSiteProject: true,
|
|
217571
|
+
projectConfig: config,
|
|
217572
|
+
name: config.name || root3.split("/").pop(),
|
|
217573
|
+
dirs: new Map,
|
|
217574
|
+
expanded: new Set,
|
|
217575
|
+
selectedPath: null,
|
|
217576
|
+
searchQuery: ""
|
|
217577
|
+
});
|
|
217578
|
+
await loadDirectory(".");
|
|
217579
|
+
await loadComponentRegistry();
|
|
217580
|
+
const conventionalDirs = [
|
|
217581
|
+
"pages",
|
|
217582
|
+
"layouts",
|
|
217583
|
+
"components",
|
|
217584
|
+
"content",
|
|
217585
|
+
"data",
|
|
217586
|
+
"public",
|
|
217587
|
+
"styles"
|
|
217588
|
+
];
|
|
217589
|
+
const entries2 = projectState.dirs.get(".") || [];
|
|
217590
|
+
for (const e20 of entries2) {
|
|
217591
|
+
if (e20.type === "directory" && conventionalDirs.includes(e20.name)) {
|
|
217592
|
+
projectState.expanded.add(e20.path || e20.name);
|
|
217593
|
+
await loadDirectory(e20.path || e20.name);
|
|
217594
|
+
}
|
|
217595
|
+
}
|
|
217596
|
+
addRecentProject(projectState.name, root3);
|
|
217597
|
+
view.leftTab = "files";
|
|
217598
|
+
renderActivityBar();
|
|
217599
|
+
renderLeftPanel();
|
|
217600
|
+
statusMessage(`Opened project: ${projectState.name}`);
|
|
217601
|
+
} catch (e20) {
|
|
217602
|
+
statusMessage(`Error: ${e20.message}`);
|
|
217603
|
+
}
|
|
217604
|
+
}
|
|
217265
217605
|
function renderFilesTemplate2() {
|
|
217266
217606
|
return renderFilesTemplate({ openProject: openProject2, openFileFromTree, renderLeftPanel });
|
|
217267
217607
|
}
|
|
@@ -217318,5 +217658,5 @@ effect(() => {
|
|
|
217318
217658
|
scheduleAutosave();
|
|
217319
217659
|
});
|
|
217320
217660
|
|
|
217321
|
-
//# debugId=
|
|
217661
|
+
//# debugId=D4BE66DA4C58521864756E2164756E21
|
|
217322
217662
|
//# sourceMappingURL=studio.js.map
|