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