vintage-frames 0.19.1 → 0.20.1

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.
Files changed (59) hide show
  1. package/README.md +1 -18
  2. package/custom-elements.json +72 -13
  3. package/dist/components/vf-desktop.d.ts +36 -6
  4. package/dist/components/vf-desktop.js +41 -23
  5. package/dist/components/vf-window.d.ts +19 -0
  6. package/dist/components/vf-window.js +33 -3
  7. package/dist/text-control.d.ts +3 -3
  8. package/docs/SPEC.md +8 -6
  9. package/editor/vscode.html-custom-data.json +10 -5
  10. package/editor/web-types.json +25 -10
  11. package/package.json +4 -34
  12. package/dist/build/app-file.d.ts +0 -21
  13. package/dist/build/app-file.js +0 -42
  14. package/dist/build/box.d.ts +0 -57
  15. package/dist/build/box.js +0 -93
  16. package/dist/build/client.d.ts +0 -12
  17. package/dist/build/frame-picture.d.ts +0 -6
  18. package/dist/build/frame-picture.js +0 -4
  19. package/dist/build/frame.d.ts +0 -11
  20. package/dist/build/frame.js +0 -44
  21. package/dist/build/index.d.ts +0 -14
  22. package/dist/build/index.js +0 -4
  23. package/dist/build/plugins.d.ts +0 -41
  24. package/dist/build/plugins.js +0 -134
  25. package/dist/build/png.d.ts +0 -24
  26. package/dist/build/png.js +0 -116
  27. package/dist/shell/alert.d.ts +0 -40
  28. package/dist/shell/alert.js +0 -41
  29. package/dist/shell/app-file.d.ts +0 -115
  30. package/dist/shell/app-file.js +0 -189
  31. package/dist/shell/catalog.d.ts +0 -250
  32. package/dist/shell/catalog.js +0 -349
  33. package/dist/shell/clock.d.ts +0 -16
  34. package/dist/shell/clock.js +0 -36
  35. package/dist/shell/filing.d.ts +0 -39
  36. package/dist/shell/filing.js +0 -68
  37. package/dist/shell/finder.d.ts +0 -180
  38. package/dist/shell/finder.js +0 -676
  39. package/dist/shell/geometry.d.ts +0 -203
  40. package/dist/shell/geometry.js +0 -257
  41. package/dist/shell/index.d.ts +0 -30
  42. package/dist/shell/index.js +0 -12
  43. package/dist/shell/pure.d.ts +0 -13
  44. package/dist/shell/pure.js +0 -6
  45. package/dist/shell/shell.d.ts +0 -177
  46. package/dist/shell/shell.js +0 -277
  47. package/dist/shell/state.d.ts +0 -88
  48. package/dist/shell/state.js +0 -103
  49. package/dist/shell/storage.d.ts +0 -14
  50. package/dist/shell/storage.js +0 -41
  51. package/dist/shell/version.d.ts +0 -2
  52. package/dist/shell/version.js +0 -4
  53. package/dist/shell/windows.d.ts +0 -278
  54. package/dist/shell/windows.js +0 -447
  55. package/dist/styles/body-strike.d.ts +0 -12
  56. package/dist/styles/body-strike.js +0 -3961
  57. package/dist/styles/display-strike.d.ts +0 -12
  58. package/dist/styles/display-strike.js +0 -4343
  59. package/dist/styles/strike.d.ts +0 -30
@@ -1,676 +0,0 @@
1
- import { snapSys as e, systemPxQuantum as t } from "../scale.js";
2
- import { prefersReducedMotion as n } from "../motion.js";
3
- import { windowChrome as r } from "../window-chrome.js";
4
- import "../index.js";
5
- import { ALIAS_KIND as i, APPLE_MENU_ITEMS as a, FOLDER as o, STARTUP_ITEMS as s, SYSTEM_FOLDER as c, TRASH as l, aliasName as u, appIdOf as d, canAlias as ee, childrenOf as te, containerOf as ne, dropTargetOf as f, enclosingFolders as re, isContainerKind as ie, isInside as ae, isKept as p, isTrashed as m, itemCount as h, resolve as oe } from "./catalog.js";
6
- import { cleanUp as se, collisions as ce, desktopLattice as le, fieldExtent as ue, fillOrder as de, folderLattice as fe, frameOf as pe, freeCellNear as me, nextFreeCell as he, pinOf as ge, pinTo as _e, trashCell as ve } from "./geometry.js";
7
- import { desktopRendered as ye } from "./windows.js";
8
- import { defineApp as g } from "./shell.js";
9
- import { fileByDrag as be } from "./filing.js";
10
- import { composeAlert as xe } from "./alert.js";
11
- //#region src/shell/finder.ts
12
- var _ = "finder", Se = 306, Ce = 300, we = {
13
- "new-folder": "New Folder",
14
- "empty-trash": "Empty Trash",
15
- paste: "Paste",
16
- "add-file": "Adding the file",
17
- "make-alias": "Make Alias"
18
- }, Te = 20, Ee = 18, v = {
19
- left: 8,
20
- top: 2
21
- }, y = {
22
- width: 12,
23
- height: 12
24
- }, b = {
25
- left: v.left - 1,
26
- top: v.top
27
- }, De = {
28
- left: b.left + y.width + 3,
29
- top: v.top
30
- }, x = [
31
- {
32
- menu: "file",
33
- label: "File",
34
- items: [
35
- [
36
- "open",
37
- "Open",
38
- "⌘O"
39
- ],
40
- ["new-folder", "New Folder"],
41
- [
42
- "close",
43
- "Close",
44
- "⌃W"
45
- ],
46
- [
47
- "make-alias",
48
- "Make Alias",
49
- "⌘M"
50
- ]
51
- ]
52
- },
53
- {
54
- menu: "edit",
55
- label: "Edit",
56
- items: [
57
- [
58
- "copy",
59
- "Copy",
60
- "⌘C"
61
- ],
62
- [
63
- "paste",
64
- "Paste",
65
- "⌘V"
66
- ],
67
- [
68
- "select-all",
69
- "Select All",
70
- "⌘A"
71
- ]
72
- ]
73
- },
74
- {
75
- menu: "view",
76
- label: "View",
77
- items: [[
78
- "arrange",
79
- "Arrange Windows",
80
- "⌘J"
81
- ]]
82
- },
83
- {
84
- menu: "special",
85
- label: "Special",
86
- items: [["clean-up", "Clean Up Desktop"], ["empty-trash", "Empty Trash…"]]
87
- }
88
- ], S = [
89
- c,
90
- a,
91
- s
92
- ], Oe = /* @__PURE__ */ new Set(["close", "make-alias"]);
93
- function C(e) {
94
- return x.map(({ menu: t, label: n, items: r }) => {
95
- let i = r.filter(([t]) => e(t)).map(([e, t, n], r) => `${Oe.has(e) && r > 0 ? "<vf-separator></vf-separator>" : ""}<vf-menu-item value="${e}"${n ? ` shortcut="${n}"` : ""}>${t}</vf-menu-item>`);
96
- return i.length ? `<vf-menu data-menu="${t}" label="${n}">${i.join("")}</vf-menu>` : "";
97
- }).join("");
98
- }
99
- var ke = (e) => e.localName === "vf-icon" && e.dataset.app != null || e instanceof HTMLTemplateElement && (e.dataset.folder != null || e.dataset.system != null);
100
- function Ae(e) {
101
- let t = (e, t) => e != null && t != null && Number.isFinite(+e) && Number.isFinite(+t) ? {
102
- left: +e,
103
- top: +t
104
- } : void 0, n = [];
105
- for (let r of [...e.children].filter(ke)) r instanceof HTMLTemplateElement ? n.push({
106
- kind: o,
107
- name: r.dataset.folder ?? null,
108
- at: t(r.dataset.left, r.dataset.top),
109
- into: r.dataset.system,
110
- children: Ae(r.content)
111
- }) : n.push({
112
- kind: "app",
113
- name: r.getAttribute("label"),
114
- app: r.dataset.app,
115
- at: t(r.getAttribute("left"), r.getAttribute("top")),
116
- children: []
117
- });
118
- return n;
119
- }
120
- function w(a) {
121
- let o = a.volumes?.trash !== !1, s = (e) => a.commands?.[e] !== !1 && (e !== "empty-trash" || o), c = [], Oe = (e) => e, w = a.seed === "markup" ? async (e) => {
122
- let t = Date.now(), n = async (r, i) => {
123
- for (let a of r) {
124
- if (a.into != null) {
125
- S.includes(a.into) && e.item(a.into) && await n(a.children, a.into);
126
- continue;
127
- }
128
- let r = await e.create({
129
- kind: a.kind,
130
- name: a.name ?? (a.app == null ? void 0 : Oe(a.app)),
131
- parent: i,
132
- ...a.at,
133
- ...a.app == null ? {} : { data: { app: a.app } },
134
- at: t++
135
- });
136
- r && a.children.length && await n(a.children, r.id);
137
- }
138
- };
139
- await n(c, null);
140
- } : a.seed;
141
- return g({
142
- id: _,
143
- name: "Finder",
144
- menus: C(s),
145
- dialogs: a.dialogs,
146
- catalog: {
147
- storage: a.storage,
148
- volumes: a.volumes,
149
- system: a.system,
150
- seed: w
151
- },
152
- init(g) {
153
- let { desktop: S, windows: C } = g, w = g.catalog, T = a.art;
154
- Oe = (e) => g.app(e)?.name ?? e;
155
- let E = a.lattice?.desktop?.cell ?? 64, D = a.lattice?.folder?.cell ?? 64, je = a.window ?? {
156
- width: 320,
157
- height: 223
158
- }, O = r({
159
- scrollbars: "both",
160
- headerHeight: Te
161
- }), Me = /* @__PURE__ */ new Map();
162
- async function k(e, t, n, r = {}) {
163
- let i = Me.get(e);
164
- if (i) return i(t);
165
- let a = xe(n, {
166
- art: T.caution ?? null,
167
- ...r
168
- });
169
- g.hold(a.dialog);
170
- try {
171
- await a.rendered();
172
- let e = g.ask(a.dialog);
173
- return a.fit(), await e;
174
- } finally {
175
- g.release(a.dialog);
176
- }
177
- }
178
- let A = (e) => (t) => {
179
- let n = t;
180
- k("failed", {
181
- action: e,
182
- error: n
183
- }, `${we[e]} failed: ${n.message}.`);
184
- }, j = S.querySelector(":scope > vf-icon-field"), Ne = !j;
185
- if (!j) {
186
- j = document.createElement("vf-icon-field"), j.label = "Desktop", j.toggleAttribute("fill-width", !0), j.toggleAttribute("fill-height", !0);
187
- let e = S.querySelector(":scope > vf-menu-bar");
188
- e ? e.after(j) : S.prepend(j);
189
- }
190
- let M = j, Pe = [...M.children].filter(ke);
191
- c = Ae(M);
192
- for (let e of Pe) e.remove();
193
- let Fe = () => C.windowsOf(_).map((e) => [C.itemOf(e), e]).filter((e) => e[0] != null), N = (e) => e.querySelector(":scope > vf-icon-field"), P = () => [[null, M], ...Fe().flatMap(([e, t]) => {
194
- let n = N(t);
195
- return n ? [[e, n]] : [];
196
- })], F = (e) => P().find(([t]) => t === e)?.[1] ?? null, I = (e) => [...e.querySelectorAll(":scope > vf-icon[data-id]")], L = () => P().flatMap(([, e]) => I(e)), R = (e) => e.dataset.id, z = (e) => L().find((t) => R(t) === e) ?? null, B = (e) => ({
197
- left: e.left ?? 0,
198
- top: e.top ?? 0
199
- }), Ie = (e) => C.itemOf(e.closest("vf-window")), Le = (e) => ({
200
- width: Math.max(0, (e.width ?? 0) - O.left - O.right),
201
- height: Math.max(0, (e.height ?? 0) - O.top - O.bottom)
202
- }), V = (e) => {
203
- if (e == null) return le(S.workArea, a.lattice?.desktop);
204
- let t = C.windowFor(e);
205
- return fe(t ? Le(t).width : 0, a.lattice?.folder);
206
- }, Re = (e) => {
207
- let t = C.windowFor(e), n = t && N(t);
208
- if (!t || !n) return;
209
- let r = ue(I(n).map(B), Le(t), { cell: D });
210
- n.width !== r.width && (n.width = r.width), n.height !== r.height && (n.height = r.height);
211
- }, ze = (n, r, i) => {
212
- if (r == null) {
213
- let r = S.workArea, a = t(n), o = (e) => Math.floor(e / a) * a, s = Math.ceil(r.top / a) * a, c = Math.max(r.left, o(r.left + r.width - E)), l = Math.max(s, o(r.top + r.height - E));
214
- n.left = Math.min(Math.max(e(i.left, n), r.left), c), n.top = Math.min(Math.max(e(i.top, n), s), l);
215
- } else n.left = e(Math.max(0, i.left), n), n.top = e(Math.max(0, i.top), n);
216
- }, Be = (e) => {
217
- if (e.id === "system-folder") return T.systemFolder ?? T.folder;
218
- if (e.id === "apple-menu-items") return T.appleMenuItems ?? T.folder;
219
- if (e.id === "startup-items") return T.startupItems ?? T.folder;
220
- if (e.kind === "folder") return T.folder;
221
- if (e.kind === "trash") return h(w.get(), "trash") ? T.trashFull : T.trash;
222
- if (e.kind === "disk") return T.disk ?? T.folder;
223
- if (e.kind === "alias") {
224
- let t = oe(w.get(), e.id);
225
- return t ? Be(t) : f(w.get(), e.id) ? T.folder : T.document;
226
- }
227
- let t = g.kind(e.kind);
228
- return (typeof t?.art == "function" ? t.art(e) : t?.art) || T.document;
229
- };
230
- function Ve(e, t) {
231
- let n = e.querySelector(":scope > vf-img > img");
232
- if (!n) {
233
- let t = document.createElement("vf-img");
234
- t.slot = "large", t.width = 32, t.height = 32, n = document.createElement("img"), n.alt = "", t.append(n), e.append(t);
235
- }
236
- n.getAttribute("src") !== t && (n.src = t);
237
- }
238
- function He(e) {
239
- let t = document.createElement("vf-icon");
240
- return t.dataset.id = e.id, t.label = e.name, t.width = E, t.selectable = !0, t.movable = !0, t;
241
- }
242
- function Ue(e, t) {
243
- let n = f(w.get(), t.id), r = n == null ? void 0 : "folder" in n ? n.folder : t.id;
244
- r === void 0 ? delete e.dataset.folder : e.dataset.folder !== r && (e.dataset.folder = r);
245
- }
246
- let H = /* @__PURE__ */ new Set(), U = /* @__PURE__ */ new WeakMap();
247
- function We(e, t, n, r) {
248
- if (t.left != null && t.top != null) {
249
- let r = `${t.left},${t.top}`;
250
- if (U.get(e) === r) return;
251
- U.set(e, r), (e.left !== t.left || e.top !== t.top) && ze(e, n, {
252
- left: t.left,
253
- top: t.top
254
- });
255
- return;
256
- }
257
- let i = I(r).filter((t) => t !== e && t.left != null && t.top != null).map(B), o = n == null && t.id === "trash" ? ve(S.workArea, a.lattice?.desktop) : he(V(n), i, n == null ? E : D);
258
- ze(e, n, o), H.add(e);
259
- }
260
- let Ge = !1, W = !1;
261
- function G() {
262
- if (!(W || !Ge)) {
263
- W = !0;
264
- try {
265
- let e = w.get(), t = new Map(L().map((e) => [R(e), e])), n = /* @__PURE__ */ new Set(), r = [], a = [];
266
- for (let [o, s] of P()) for (let c of te(e, o)) {
267
- let e = t.get(c.id) ?? He(c);
268
- e.parentElement !== s && (s.append(e), e.left = void 0, e.top = void 0, U.delete(e)), n.add(e), e.label !== c.name && (e.label = c.name), e.editable = !p(c.id) && g.kind(c.kind)?.editable !== !1, e.alias = c.kind === i, Ue(e, c), Ve(e, Be(c));
269
- let l = c.kind === "app" ? C.hasWindows(d(c) ?? "") : C.isOpen(c.id);
270
- e.open !== l && (e.open = l);
271
- let u = () => We(e, c, o, s);
272
- c.left != null && c.top != null ? r.push(u) : a.push(u);
273
- }
274
- for (let e of t.values()) n.has(e) || e.remove();
275
- for (let e of [...r, ...a]) e();
276
- for (let [e, t] of Fe()) {
277
- let n = N(t), r = w.item(e)?.name;
278
- n && r != null && n.label !== r && (n.label = r), Je(e), Re(e);
279
- }
280
- } finally {
281
- W = !1;
282
- }
283
- Ke();
284
- }
285
- }
286
- let K = !1;
287
- function Ke() {
288
- if (K = !1, !H.size) return;
289
- let e = /* @__PURE__ */ new Map();
290
- for (let t of H) t.isConnected && t.left != null && t.top != null && e.set(R(t), B(t));
291
- H.clear(), w.place(e);
292
- }
293
- g.on(S, "vf-placement-change", (e) => {
294
- let t = e.target;
295
- t.localName === "vf-icon" && t.dataset.id != null && (H.add(t), !K && (K = !0, queueMicrotask(Ke)));
296
- }), g.onDispose(w.subscribe(G)), g.onDispose(C.onWindows(G));
297
- function qe() {
298
- let e = document.createElement("vf-img");
299
- e.dataset.trashMark = "", e.width = y.width, e.height = y.height, e.left = b.left, e.top = b.top;
300
- let t = document.createElement("img");
301
- return t.alt = "in the Trash", t.src = T.trashMark, e.append(t), e;
302
- }
303
- function Je(e) {
304
- let t = C.windowFor(e)?.querySelector(":scope > [slot=\"header\"]"), n = t?.querySelector(":scope > vf-label[data-count]");
305
- if (!t || !n) return;
306
- let r = w.get(), i = h(r, e), a = `${i} item${i === 1 ? "" : "s"}`;
307
- n.textContent !== a && (n.textContent = a);
308
- let o = !!T.trashMark && m(r, e), s = t.querySelector(":scope > vf-img[data-trash-mark]");
309
- o && !s ? t.prepend(qe()) : !o && s && s.remove();
310
- let c = o ? De : v;
311
- n.left !== c.left && (n.left = c.left);
312
- }
313
- function Ye(e) {
314
- let t = w.item(e)?.name ?? "", n = document.createElement("vf-window");
315
- n.heading = t, n.closable = !0, n.movable = !0, n.outlineDrag = !0, n.resizable = !0, n.scrollbars = "both", n.headerHeight = Te, n.width = je.width, n.height = je.height;
316
- let r = document.createElement("vf-container");
317
- r.slot = "header", r.toggleAttribute("fill-width", !0), r.height = Ee, r.rule = "bottom";
318
- let i = document.createElement("vf-label");
319
- i.face = "body", i.dataset.count = "", i.left = v.left, i.top = v.top, r.append(i);
320
- let a = document.createElement("vf-icon-field");
321
- return a.label = t, a.left = 0, a.top = 0, n.append(r, a), n;
322
- }
323
- g.on(S, "vf-resize", (e) => {
324
- if (!e.detail?.commit || C.appOf(e.target) !== "finder") return;
325
- let t = C.itemOf(e.target);
326
- t != null && Re(t);
327
- });
328
- function Xe(e) {
329
- k("original-missing", { alias: e }, `The alias “${e.name}” could not be opened, because the original item could not be found.`);
330
- }
331
- function Ze(e, t) {
332
- let n = w.item(e);
333
- if (!n) return;
334
- let r = oe(w.get(), e);
335
- if (!r) {
336
- Xe(n);
337
- return;
338
- }
339
- ie(r.kind) ? C.open({
340
- app: _,
341
- item: r.id,
342
- from: t,
343
- create: () => Ye(r.id)
344
- }) : g.kind(r.kind)?.open(r, t);
345
- }
346
- g.on(S, "vf-open", (e) => {
347
- let t = e.target;
348
- t.localName === "vf-icon" && t.dataset.id != null && (t.selected && J().length > 1 ? it() : Ze(R(t), t.cellRect()));
349
- });
350
- let Qe = (e) => {
351
- let t = w.get().items.filter((t) => t.kind === "app" && d(t) === e);
352
- return t.find((e) => z(e.id)) ?? t[0] ?? null;
353
- }, $e = (e, t) => w.item(e) ?? (t == null ? null : Qe(t));
354
- g.onDispose(C.setHome((e, t) => {
355
- let n = $e(e, t);
356
- if (!n) return null;
357
- let r = z(n.id)?.cellRect();
358
- if (r) return r;
359
- for (let e of re(w.get(), n.parent)) {
360
- let t = z(e)?.cellRect();
361
- if (t) return t;
362
- }
363
- return null;
364
- }, (e, t) => {
365
- let n = e == null && t == null ? null : $e(e, t), r = I(M), i = n ? z(n.id) : r.find((e) => e.selected) ?? r[0] ?? null;
366
- return i?.checkVisibility() ? (i.focus({ preventScroll: !0 }), !0) : !1;
367
- })), g.on(M, "pointerdown", () => S.clearActive());
368
- let et = (e) => {
369
- let t = e.target;
370
- return t.localName === "vf-icon" && t.dataset.id != null;
371
- };
372
- g.on(S, "vf-change", (e) => {
373
- if (!et(e)) return;
374
- let t = e.target, { label: n, previous: r } = e.detail;
375
- w.rename(R(t), n).catch(() => {
376
- t.label = r;
377
- });
378
- });
379
- let tt = !1;
380
- g.on(S, "vf-name-too-long", (e) => {
381
- if (!et(e) || tt) return;
382
- tt = !0;
383
- let { limit: t } = e.detail;
384
- k("name-too-long", { limit: t }, `That name is too long. A name can have up to ${t} characters.`).finally(() => {
385
- tt = !1;
386
- });
387
- }), g.on(S, "vf-name-rejected", (e) => {
388
- et(e) && k("name-rejected", {}, "An item needs a name.");
389
- }), g.onDispose(be(S, {
390
- folderOfWindow: (e) => C.appOf(e) === "finder" ? C.itemOf(e) ?? void 0 : void 0,
391
- folderOfIcon: (e) => e.dataset.folder,
392
- containerOf: (e) => e.dataset.id == null ? void 0 : Ie(e),
393
- canFile: (e, t) => {
394
- let n = w.get(), r = t == null ? null : f(n, t);
395
- return t != null && !r ? !1 : e.every((e) => {
396
- let t = e.dataset.id;
397
- return t == null || p(t) ? !1 : !r || "missing" in r || t !== r.folder && !ae(n, r.folder, t);
398
- });
399
- },
400
- file: (e, t, n) => {
401
- let r = null;
402
- if (t != null) {
403
- let e = f(w.get(), t);
404
- if (!e) return;
405
- if ("missing" in e) return Xe(e.missing);
406
- r = e.folder;
407
- }
408
- let i = new Map([...n].map(([e, t]) => [R(e), t]));
409
- w.move(e.map(R), r, i).catch((e) => {
410
- k("move-failed", { error: e }, `The items couldn’t be moved: ${e.message}.`);
411
- });
412
- }
413
- }));
414
- let nt = /* @__PURE__ */ new WeakMap(), q = 0;
415
- g.onDispose(C.onRaster((t, n) => {
416
- M.dragIcons([]);
417
- let r = {
418
- width: E,
419
- height: E
420
- }, i = pe(S.workArea.top);
421
- for (let a of I(M)) {
422
- let o = {
423
- ...B(a),
424
- ...r
425
- }, s = nt.get(a), c = !s || s.left !== o.left || s.top !== o.top ? ge(o, t, i) : s.pin, l = _e(c, n, i, { size: r });
426
- a.left = e(l.left, a), a.top = e(l.top, a), nt.set(a, {
427
- pin: c,
428
- left: a.left,
429
- top: a.top
430
- });
431
- }
432
- a.cleanUpAfterResize && (window.clearTimeout(q), q = window.setTimeout(() => {
433
- q = 0, ce(I(M).map((e) => ({
434
- ...B(e),
435
- ...r
436
- }))).size && rt(null);
437
- }, Ce));
438
- })), g.onDispose(() => window.clearTimeout(q));
439
- let J = () => {
440
- let e = new Set(L().filter((e) => e.selected).map(R));
441
- return w.get().items.filter((t) => e.has(t.id));
442
- }, Y = (e) => {
443
- let t = new Set(e);
444
- for (let e of L()) e.setSelected(t.has(R(e)));
445
- }, X = () => {
446
- let e = S.activeWindow;
447
- return e && C.appOf(e) === "finder" ? C.itemOf(e) : null;
448
- };
449
- async function rt(e) {
450
- let t = F(e);
451
- if (!t) return;
452
- let n = V(e), r = I(t), i = se(n, r.map(B)), a = r.map((e, t) => ({
453
- icon: e,
454
- ...i[t]
455
- })).sort((e, t) => de(n, e, t));
456
- await t.dragIcons(a);
457
- }
458
- async function it() {
459
- let e = n() ? 0 : Se;
460
- for (let [t, n] of J().entries()) t && e && await new Promise((t) => setTimeout(t, e)), Ze(n.id, z(n.id)?.cellRect() ?? null);
461
- }
462
- async function at(e) {
463
- let t = z(e);
464
- t && (Y([e]), await t.updateComplete, t.startEditing());
465
- }
466
- let Z = () => w.get().available ? !0 : (k("storage-unavailable", {}, "Files can’t be saved in this browser session. A private window, perhaps.", { label: "Storage Unavailable" }), !1);
467
- async function ot() {
468
- if (!Z()) return;
469
- let e = await w.create({ parent: X() }).catch(A("new-folder"));
470
- e && await at(e.id);
471
- }
472
- let st = (e) => ee(w.get(), e.id);
473
- async function ct() {
474
- if (!Z()) return;
475
- let e = /* @__PURE__ */ new Map(), t = [];
476
- try {
477
- for (let n of J().filter(st)) {
478
- let r = w.get(), a = oe(r, n.id), o = ne(r, n.parent), s = z(n.id), c = F(o), l;
479
- if (s && c) {
480
- let t = e.get(o) ?? I(c).map(B);
481
- l = me(V(o), B(s), t, o == null ? E : D), e.set(o, [...t, l]);
482
- }
483
- let d = await w.create({
484
- kind: i,
485
- name: u(r, o, n.name),
486
- parent: o,
487
- data: {
488
- original: a.id,
489
- kind: a.kind
490
- },
491
- ...l
492
- });
493
- d && t.push(d.id);
494
- }
495
- } catch (e) {
496
- A("make-alias")(e);
497
- }
498
- t.length && Y(t);
499
- }
500
- async function lt() {
501
- let e = h(w.get(), l);
502
- if (!o || !e) return;
503
- let t = w.trashSize(), n = Math.ceil(t / 1024), r = e === 1 ? `The Trash contains 1 item, which uses ${n}K of disk space. Are you sure you want to permanently remove it?` : `The Trash contains ${e} items, which use ${n}K of disk space. Are you sure you want to permanently remove these items?`;
504
- await k("empty-trash", {
505
- count: e,
506
- bytes: t
507
- }, r, {
508
- label: "Empty Trash",
509
- buttons: [{
510
- label: "Cancel",
511
- value: "cancel"
512
- }, {
513
- label: "OK",
514
- value: "ok",
515
- default: !0
516
- }]
517
- }) === "ok" && await w.emptyTrash().catch(A("empty-trash"));
518
- }
519
- let Q = {
520
- ids: [],
521
- text: ""
522
- }, ut = (e) => e.replace(/\r\n?/g, "\n").trimEnd();
523
- async function dt() {
524
- let e = J().filter((e) => !p(e.id));
525
- if (!e.length) return;
526
- let t = e.map((e) => e.name).join("\n");
527
- Q = {
528
- ids: e.map((e) => e.id),
529
- text: t
530
- };
531
- let n = e.find((e) => g.kind(e.kind)?.export);
532
- try {
533
- let e = n ? await g.kind(n.kind).export(n) : null;
534
- if (e?.type && e.type !== "text/plain" && typeof ClipboardItem < "u") {
535
- await navigator.clipboard.write([new ClipboardItem({
536
- "text/plain": new Blob([t], { type: "text/plain" }),
537
- [e.type]: e
538
- })]);
539
- return;
540
- }
541
- } catch {}
542
- try {
543
- await navigator.clipboard?.writeText(t);
544
- } catch {}
545
- }
546
- async function ft(e, t) {
547
- for (let n of g.kinds.values()) if (n.claim && await n.claim(e, t)) return !0;
548
- return !1;
549
- }
550
- let pt = () => [...g.kinds.values()].some((e) => e.claim);
551
- async function mt() {
552
- try {
553
- if (navigator.clipboard?.read) {
554
- let e = null, t = [];
555
- for (let n of await navigator.clipboard.read()) for (let r of n.types) {
556
- let i = await n.getType(r);
557
- r === "text/plain" ? e ??= await i.text() : t.push(i);
558
- }
559
- return {
560
- text: e,
561
- files: t
562
- };
563
- }
564
- if (navigator.clipboard?.readText) return {
565
- text: await navigator.clipboard.readText(),
566
- files: []
567
- };
568
- } catch {}
569
- return null;
570
- }
571
- async function ht(e) {
572
- if (!Z()) return;
573
- let t = X();
574
- if (m(w.get(), t)) return;
575
- let n = e === void 0 ? await mt() : e, r = Q.ids.length > 0 && (n == null || n.text != null && ut(n.text) === ut(Q.text));
576
- try {
577
- if (r) {
578
- let e = await w.copy(Q.ids, t);
579
- e.length && Y(e.map((e) => e.id));
580
- } else for (let e of n?.files ?? []) await ft(e, t);
581
- } catch (e) {
582
- A("paste")(e);
583
- }
584
- }
585
- g.on(document, "paste", (e) => {
586
- if (!s("paste") || C.front !== "finder" || g.modalOpen() || g.typing()) return;
587
- let t = e.clipboardData;
588
- t && (e.preventDefault(), ht({
589
- text: t.getData("text/plain") || null,
590
- files: [...t.files]
591
- }));
592
- });
593
- let gt = (e) => [...e.dataTransfer?.types ?? []].includes("Files");
594
- g.on(S, "dragover", (e) => {
595
- gt(e) && pt() && e.preventDefault();
596
- }), g.on(S, "drop", (e) => {
597
- if (!gt(e) || !pt()) return;
598
- e.preventDefault();
599
- let t = e, n = [...t.dataTransfer?.files ?? []], r = document.elementsFromPoint(t.clientX, t.clientY).find((e) => e.localName === "vf-window");
600
- if (r && C.appOf(r) !== "finder" || (r ? S.bringToFront(r) : S.clearActive(), !Z())) return;
601
- let i = r ? C.itemOf(r) : null;
602
- m(w.get(), i) || (async () => {
603
- for (let e of n) await ft(e, i);
604
- })().catch(A("add-file"));
605
- });
606
- let _t = {
607
- open: () => void it(),
608
- "new-folder": () => void ot(),
609
- close: () => {
610
- let e = X(), t = e == null ? null : C.windowFor(e);
611
- t && C.requestClose(t);
612
- },
613
- "make-alias": () => void ct(),
614
- copy: () => void dt(),
615
- paste: () => void ht(),
616
- "select-all": () => {
617
- let e = F(X());
618
- e && Y(I(e).map(R));
619
- },
620
- arrange: () => C.arrange(),
621
- "clean-up": () => void rt(X()),
622
- "empty-trash": () => void lt()
623
- }, $ = (e, t) => {
624
- s(e) && g.gate(g.item(e), t);
625
- };
626
- if ($("open", () => !g.typing() && J().length > 0), $("new-folder", () => !m(w.get(), X())), $("close", () => X() != null), $("make-alias", () => !g.typing() && J().some(st)), $("copy", () => !g.typing() && J().some((e) => !p(e.id))), $("paste", () => !g.typing() && !m(w.get(), X())), $("select-all", () => !g.typing()), $("arrange", () => !C.arranged()), $("empty-trash", () => h(w.get(), l) > 0), s("clean-up")) {
627
- let e = g.item("clean-up");
628
- g.gate(e, () => {
629
- let t = X() == null ? "Clean Up Desktop" : "Clean Up Window";
630
- return e.textContent !== t && (e.textContent = t), !0;
631
- });
632
- }
633
- let vt = !0, yt = (e) => {
634
- let t = g.menus.find((t) => t.dataset.menu === e);
635
- if (t) return t;
636
- if (!vt) throw Error(`vintage-frames/shell (finder): no ${e} menu; add to it from extend`);
637
- let n = document.createElement("vf-menu");
638
- n.dataset.menu = e, n.label = x.find((t) => t.menu === e).label;
639
- let r = x.map((e) => e.menu), i = g.menus.findIndex((t) => r.indexOf(t.dataset.menu) > r.indexOf(e));
640
- return g.menus.splice(i < 0 ? g.menus.length : i, 0, n), n;
641
- }, bt = {
642
- catalog: w,
643
- selection: J,
644
- select: Y,
645
- activeFolder: X,
646
- open: ({ item: e, from: t = null } = {}) => {
647
- e != null && Ze(e, t);
648
- },
649
- rename: at,
650
- cleanUp: rt,
651
- iconFor: z,
652
- addCommand(e) {
653
- let t = yt(e.menu);
654
- e.separator && t.append(document.createElement("vf-separator"));
655
- let n = document.createElement("vf-menu-item");
656
- return n.setAttribute("value", e.value), e.shortcut && n.setAttribute("shortcut", e.shortcut), n.textContent = e.label, t.append(n), _t[e.value] = e.run, e.enabled && g.gate(n, e.enabled), n;
657
- },
658
- alertWith(e, t) {
659
- Me.set(e, t);
660
- },
661
- storageReady: Z
662
- };
663
- a.extend?.(bt, g), vt = !1, g.onMenu((e) => _t[e]?.());
664
- let xt = !1;
665
- return g.onDispose(() => {
666
- xt = !0;
667
- for (let e of I(M)) e.remove();
668
- Ne ? M.remove() : M.append(...Pe);
669
- }), ye(S).then(() => {
670
- xt || (Ge = !0, G());
671
- }), bt;
672
- }
673
- });
674
- }
675
- //#endregion
676
- export { _ as FINDER, w as finder };