@nsnanocat/preference-panes 1.2.4 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +64 -7
- package/dist/home.html +1032 -0
- package/dist/module/index.html +2 -3
- package/dist/module/index.mjs +127 -59
- package/dist/module/navigation.mjs +21 -5
- package/dist/preference-panes.mjs +111 -58
- package/package.json +3 -2
- package/src/browser/ModuleFrame.mjs +21 -5
- package/src/browser/Navigation.d.mts +3 -3
- package/src/browser/boxjs.mjs +38 -8
- package/src/browser/client.d.mts +2 -2
- package/src/browser/client.mjs +51 -21
- package/src/browser/home.d.mts +54 -0
- package/src/browser/home.html +16 -0
- package/src/browser/home.mjs +441 -0
- package/src/browser/index.d.ts +2 -0
- package/src/browser/index.mjs +16 -1
- package/src/browser/module.html +1 -2
- package/src/browser/panel.mjs +22 -29
- package/src/browser/{panel.css → styles.css} +245 -3
- package/src/index.d.ts +8 -0
- package/dist/web.js +0 -1232
- package/src/web.mjs +0 -99
package/src/browser/index.mjs
CHANGED
|
@@ -38,7 +38,22 @@ class ModulePage {
|
|
|
38
38
|
const match = /^\/settings\/([a-zA-Z0-9_-]+)\/?$/.exec(this.#window.location.pathname);
|
|
39
39
|
const module = embedded ?? match?.[1];
|
|
40
40
|
if (!module) throw new TypeError("Open a concrete module URL");
|
|
41
|
-
const
|
|
41
|
+
const frame = this.#window.frameElement?.dataset;
|
|
42
|
+
const base = frame?.preferencePanesBase ?? this.#window.location.href;
|
|
43
|
+
this.#window.document.querySelector("link[data-preference-panes-stylesheet]")?.remove();
|
|
44
|
+
const stylesheetSource = frame?.preferencePanesStylesheet ?? new URLSearchParams(this.#window.location.search).get("css")?.trim();
|
|
45
|
+
if (stylesheetSource) {
|
|
46
|
+
const stylesheet = new URL(stylesheetSource, base);
|
|
47
|
+
if (!["http:", "https:"].includes(stylesheet.protocol)) throw new TypeError("CSS resource must use HTTP(S)");
|
|
48
|
+
const link = this.#window.document.createElement("link");
|
|
49
|
+
link.dataset.preferencePanesStylesheet = "true";
|
|
50
|
+
link.rel = "stylesheet";
|
|
51
|
+
link.href = stylesheet.href;
|
|
52
|
+
this.#window.document.head.append(link);
|
|
53
|
+
}
|
|
54
|
+
const jsonSource = frame?.preferencePanesJson ?? new URLSearchParams(this.#window.location.search).get("json")?.trim();
|
|
55
|
+
const source = new URL(jsonSource || `/api/${encodeURIComponent(module)}`, base);
|
|
56
|
+
if (!["http:", "https:"].includes(source.protocol)) throw new TypeError("BoxJS resource must use HTTP(S)");
|
|
42
57
|
const response = await fetch(source, { cache: "no-store", credentials: "omit", headers: { Accept: "application/json" } });
|
|
43
58
|
if (response.status !== 200) throw new Error(`HTTP ${response.status}`);
|
|
44
59
|
const boxjs = await response.json();
|
package/src/browser/module.html
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="zh-CN">
|
|
2
|
+
<html lang="zh-CN" class="pp-page">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
|
|
6
6
|
<meta name="color-scheme" content="light dark">
|
|
7
7
|
<!--__PREFERENCE_PANES_JSON__-->
|
|
8
8
|
<title>Module Preferences</title>
|
|
9
|
-
<style>body { margin: 0; }</style>
|
|
10
9
|
<!--__PREFERENCE_PANES_STYLESHEET__-->
|
|
11
10
|
</head>
|
|
12
11
|
<body>
|
package/src/browser/panel.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActionMenu } from "./ActionMenu.mjs";
|
|
2
2
|
import { validValue } from "./boxjs.mjs";
|
|
3
3
|
import { PreferencesClient } from "./client.mjs";
|
|
4
|
-
import { fieldControl, element as node, requestConfirmation, requestURLNavigation,
|
|
4
|
+
import { fieldControl, element as node, requestConfirmation, requestURLNavigation, settingRow, statusView } from "./components.mjs";
|
|
5
5
|
import { Navigation } from "./Navigation.mjs";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -112,17 +112,17 @@ export class PreferencesPanel {
|
|
|
112
112
|
const notify = event => {
|
|
113
113
|
if (destroyed) return;
|
|
114
114
|
let message;
|
|
115
|
-
switch (
|
|
116
|
-
case
|
|
115
|
+
switch (event.kind === "error" ? "error" : event.operation) {
|
|
116
|
+
case "error":
|
|
117
117
|
message = `操作失败:${event.message}`;
|
|
118
118
|
break;
|
|
119
|
-
case
|
|
119
|
+
case "delete":
|
|
120
120
|
message = "删除成功";
|
|
121
121
|
break;
|
|
122
|
-
case
|
|
122
|
+
case "clearCaches":
|
|
123
123
|
message = "Caches 已清空";
|
|
124
124
|
break;
|
|
125
|
-
case
|
|
125
|
+
case "reset":
|
|
126
126
|
message = "设置已重置";
|
|
127
127
|
break;
|
|
128
128
|
default:
|
|
@@ -245,21 +245,6 @@ export class PreferencesPanel {
|
|
|
245
245
|
});
|
|
246
246
|
return queue;
|
|
247
247
|
}
|
|
248
|
-
const metadata = definition.metadata;
|
|
249
|
-
if (metadata) {
|
|
250
|
-
const info = node("div", "pp-module-info");
|
|
251
|
-
const details = node("div", "pp-module-details");
|
|
252
|
-
for (const description of [metadata.author, metadata.desc ?? metadata.description, ...(metadata.descs ?? [])]) if (description) details.append(node("p", "pp-description", description));
|
|
253
|
-
if (metadata.repo) {
|
|
254
|
-
const link = node("a", "pp-module-source", "项目主页");
|
|
255
|
-
link.href = resourceURL(metadata.repo);
|
|
256
|
-
link.target = "_blank";
|
|
257
|
-
link.rel = "noopener noreferrer";
|
|
258
|
-
details.append(link);
|
|
259
|
-
}
|
|
260
|
-
info.append(details);
|
|
261
|
-
view.append(info);
|
|
262
|
-
}
|
|
263
248
|
for (const field of definition.fields) {
|
|
264
249
|
const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
|
|
265
250
|
const group = match?.[1] ?? "通用";
|
|
@@ -300,8 +285,8 @@ export class PreferencesPanel {
|
|
|
300
285
|
let write;
|
|
301
286
|
let inputContainer = row;
|
|
302
287
|
let eventName = "change";
|
|
303
|
-
switch (
|
|
304
|
-
case
|
|
288
|
+
switch (field.control === "url" ? "url" : field.options ? (field.type === "array" ? "checkboxes" : "selects") : field.type) {
|
|
289
|
+
case "url": {
|
|
305
290
|
const link = node("a", "pp-choice-link", "打开");
|
|
306
291
|
link.setAttribute("aria-label", field.name);
|
|
307
292
|
link.rel = "noopener noreferrer";
|
|
@@ -317,7 +302,7 @@ export class PreferencesPanel {
|
|
|
317
302
|
});
|
|
318
303
|
break;
|
|
319
304
|
}
|
|
320
|
-
case
|
|
305
|
+
case "selects": {
|
|
321
306
|
const select = node("select", "");
|
|
322
307
|
select.setAttribute("aria-label", field.name);
|
|
323
308
|
field.options.forEach((option, index) => {
|
|
@@ -332,7 +317,7 @@ export class PreferencesPanel {
|
|
|
332
317
|
read = () => field.options[select.selectedIndex]?.key;
|
|
333
318
|
break;
|
|
334
319
|
}
|
|
335
|
-
case
|
|
320
|
+
case "checkboxes": {
|
|
336
321
|
const page = node("section", "pp-choice-page");
|
|
337
322
|
if (field.description) page.append(node("p", "pp-description", field.description));
|
|
338
323
|
const choices = node("div", "pp-rows");
|
|
@@ -376,7 +361,7 @@ export class PreferencesPanel {
|
|
|
376
361
|
};
|
|
377
362
|
break;
|
|
378
363
|
}
|
|
379
|
-
case
|
|
364
|
+
case "boolean": {
|
|
380
365
|
const toggle = node("input", "pp-switch");
|
|
381
366
|
toggle.type = "checkbox";
|
|
382
367
|
toggle.setAttribute("switch", "");
|
|
@@ -414,7 +399,12 @@ export class PreferencesPanel {
|
|
|
414
399
|
growingInputs.push(grow);
|
|
415
400
|
}
|
|
416
401
|
eventName = "input";
|
|
417
|
-
if (!multiline)
|
|
402
|
+
if (!multiline) {
|
|
403
|
+
input.type = field.type === "number" ? "number" : "text";
|
|
404
|
+
input.autocapitalize = "off";
|
|
405
|
+
input.setAttribute("autocorrect", "off");
|
|
406
|
+
input.spellcheck = false;
|
|
407
|
+
}
|
|
418
408
|
write = value => {
|
|
419
409
|
input.value = field.type === "array" ? JSON.stringify(value ?? []) : (value ?? "");
|
|
420
410
|
grow();
|
|
@@ -517,7 +507,9 @@ export class PreferencesPanel {
|
|
|
517
507
|
});
|
|
518
508
|
handlers.set("clearCaches", async () => {
|
|
519
509
|
if (saving) return;
|
|
520
|
-
|
|
510
|
+
const shared = definition.cachePath && definition.cachePath !== `@${definition.storageKey}.${active}.Caches`;
|
|
511
|
+
const message = shared ? `清空共享缓存 ${definition.cachePath}?使用该缓存的其它模块也会受影响。` : `清空 ${active} 的全部 Caches?`;
|
|
512
|
+
if (!(await requestConfirmation(window, message)) || destroyed || saving) return;
|
|
521
513
|
return perform(
|
|
522
514
|
() => client.clearCaches(),
|
|
523
515
|
() => {
|
|
@@ -527,7 +519,8 @@ export class PreferencesPanel {
|
|
|
527
519
|
});
|
|
528
520
|
handlers.set("reset", async () => {
|
|
529
521
|
if (saving) return;
|
|
530
|
-
|
|
522
|
+
const message = definition.resetPaths ? `重置 ${definition.metadata?.name ?? active} 的设置?只删除本页面的设置,保留共享存储中的其它设置和缓存。` : `重置 ${active} 的设置?这将删除该模块的 Settings、Caches 和其它持久化数据。`;
|
|
523
|
+
if (!(await requestConfirmation(window, message)) || destroyed || saving) return;
|
|
531
524
|
return perform(() => client.reset(), controls);
|
|
532
525
|
});
|
|
533
526
|
navigation?.destroy();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。
|
|
2
2
|
* Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */
|
|
3
|
-
|
|
3
|
+
:root {
|
|
4
4
|
--pp-text: #18191c;
|
|
5
5
|
--pp-background: #f6f7f8;
|
|
6
6
|
--pp-surface: #fff;
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
--pp-muted: #797f87;
|
|
10
10
|
--pp-accent: #1677ff;
|
|
11
11
|
--pp-warning: #9a6700;
|
|
12
|
+
--pp-host-height: 0px;
|
|
13
|
+
--pp-keyboard-height: 0px;
|
|
14
|
+
}
|
|
15
|
+
.pp-panel {
|
|
12
16
|
font:
|
|
13
17
|
15px / 1.5 -apple-system,
|
|
14
18
|
BlinkMacSystemFont,
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
overflow: hidden;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
:root[data-theme="dark"]
|
|
33
|
+
:root[data-theme="dark"] {
|
|
30
34
|
--pp-text: #f1f2f3;
|
|
31
35
|
--pp-background: #0d0e0f;
|
|
32
36
|
--pp-surface: #18191c;
|
|
@@ -145,6 +149,7 @@
|
|
|
145
149
|
min-height: 36px;
|
|
146
150
|
padding: 8px 10px;
|
|
147
151
|
font: inherit;
|
|
152
|
+
font-size: 16px;
|
|
148
153
|
color: var(--pp-text);
|
|
149
154
|
background: var(--pp-field);
|
|
150
155
|
border: 0;
|
|
@@ -262,7 +267,7 @@
|
|
|
262
267
|
box-sizing: border-box;
|
|
263
268
|
width: 28px;
|
|
264
269
|
height: 28px;
|
|
265
|
-
border: 3px solid
|
|
270
|
+
border: 3px solid var(--pp-border, #8884);
|
|
266
271
|
border-top-color: var(--pp-accent, AccentColor);
|
|
267
272
|
border-radius: 50%;
|
|
268
273
|
animation: pp-status-spin 0.8s linear infinite;
|
|
@@ -313,3 +318,240 @@
|
|
|
313
318
|
outline: 2px solid var(--pp-accent);
|
|
314
319
|
outline-offset: -2px;
|
|
315
320
|
}
|
|
321
|
+
|
|
322
|
+
/* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。
|
|
323
|
+
* The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */
|
|
324
|
+
:root.pp-page {
|
|
325
|
+
color-scheme: light dark;
|
|
326
|
+
}
|
|
327
|
+
.pp-page body {
|
|
328
|
+
margin: 0;
|
|
329
|
+
font:
|
|
330
|
+
16px / 1.5 -apple-system,
|
|
331
|
+
BlinkMacSystemFont,
|
|
332
|
+
"Segoe UI",
|
|
333
|
+
sans-serif;
|
|
334
|
+
background: var(--pp-background, Canvas);
|
|
335
|
+
color: var(--pp-text, CanvasText);
|
|
336
|
+
}
|
|
337
|
+
[data-preference-panes-pages] {
|
|
338
|
+
position: relative;
|
|
339
|
+
min-height: calc(100vh - var(--pp-host-height));
|
|
340
|
+
background: inherit;
|
|
341
|
+
}
|
|
342
|
+
[data-preference-panes-module-page],
|
|
343
|
+
[data-preference-panes-link-page] {
|
|
344
|
+
position: fixed;
|
|
345
|
+
inset: var(--pp-host-height) 0 0;
|
|
346
|
+
background: inherit;
|
|
347
|
+
z-index: 1;
|
|
348
|
+
box-shadow: -8px 0 24px #00000014;
|
|
349
|
+
}
|
|
350
|
+
[data-preference-panes-module-page] iframe,
|
|
351
|
+
[data-preference-panes-link-page] iframe {
|
|
352
|
+
display: block;
|
|
353
|
+
border: 0;
|
|
354
|
+
width: 100%;
|
|
355
|
+
height: 100%;
|
|
356
|
+
background: inherit;
|
|
357
|
+
}
|
|
358
|
+
[data-module-message] {
|
|
359
|
+
position: absolute;
|
|
360
|
+
inset: 0;
|
|
361
|
+
margin: 0;
|
|
362
|
+
padding: 20px;
|
|
363
|
+
background: inherit;
|
|
364
|
+
}
|
|
365
|
+
[data-module-message][hidden] {
|
|
366
|
+
display: none;
|
|
367
|
+
}
|
|
368
|
+
.pp-host-header {
|
|
369
|
+
position: sticky;
|
|
370
|
+
top: 0;
|
|
371
|
+
z-index: 2;
|
|
372
|
+
display: grid;
|
|
373
|
+
grid-template-columns: 44px minmax(0, 1fr) 44px;
|
|
374
|
+
align-items: center;
|
|
375
|
+
min-height: 44px;
|
|
376
|
+
padding: env(safe-area-inset-top) max(12px, env(safe-area-inset-right)) 0 max(12px, env(safe-area-inset-left));
|
|
377
|
+
border-bottom: 1px solid var(--pp-border, #8884);
|
|
378
|
+
background: var(--pp-surface, Canvas);
|
|
379
|
+
color: var(--pp-accent, Highlight);
|
|
380
|
+
font-size: 17px;
|
|
381
|
+
}
|
|
382
|
+
.pp-host-title {
|
|
383
|
+
text-align: center;
|
|
384
|
+
color: var(--pp-text, CanvasText);
|
|
385
|
+
font-weight: 600;
|
|
386
|
+
overflow: hidden;
|
|
387
|
+
text-overflow: ellipsis;
|
|
388
|
+
white-space: nowrap;
|
|
389
|
+
}
|
|
390
|
+
.pp-host-back {
|
|
391
|
+
border: 0;
|
|
392
|
+
background: none;
|
|
393
|
+
color: inherit;
|
|
394
|
+
width: 44px;
|
|
395
|
+
height: 44px;
|
|
396
|
+
padding: 8px;
|
|
397
|
+
font:
|
|
398
|
+
32px / 1 -apple-system,
|
|
399
|
+
sans-serif;
|
|
400
|
+
cursor: pointer;
|
|
401
|
+
}
|
|
402
|
+
.pp-host-back[hidden] {
|
|
403
|
+
visibility: hidden;
|
|
404
|
+
display: block;
|
|
405
|
+
}
|
|
406
|
+
.pp-host-toast {
|
|
407
|
+
position: fixed;
|
|
408
|
+
z-index: 3;
|
|
409
|
+
bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));
|
|
410
|
+
left: 50%;
|
|
411
|
+
transform: translateX(-50%);
|
|
412
|
+
max-width: calc(100% - 48px);
|
|
413
|
+
padding: 10px 18px;
|
|
414
|
+
border-radius: 12px;
|
|
415
|
+
background: #222e;
|
|
416
|
+
color: #fff;
|
|
417
|
+
font-size: 14px;
|
|
418
|
+
text-align: center;
|
|
419
|
+
}
|
|
420
|
+
.pp-host-toast[hidden] {
|
|
421
|
+
display: none;
|
|
422
|
+
}
|
|
423
|
+
.pp-host-error {
|
|
424
|
+
margin: 24px;
|
|
425
|
+
padding: 16px;
|
|
426
|
+
border: 1px solid var(--pp-danger, #e45656);
|
|
427
|
+
border-radius: 12px;
|
|
428
|
+
font-size: 16px;
|
|
429
|
+
overflow-wrap: anywhere;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.pp-home {
|
|
433
|
+
max-width: 1000px;
|
|
434
|
+
margin: auto;
|
|
435
|
+
padding: 24px max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
|
|
436
|
+
}
|
|
437
|
+
.pp-home-logo {
|
|
438
|
+
display: block;
|
|
439
|
+
width: 64px;
|
|
440
|
+
height: 64px;
|
|
441
|
+
margin: 0 auto 24px;
|
|
442
|
+
object-fit: contain;
|
|
443
|
+
}
|
|
444
|
+
.pp-home-entries {
|
|
445
|
+
display: flex;
|
|
446
|
+
flex-wrap: wrap;
|
|
447
|
+
justify-content: space-around;
|
|
448
|
+
row-gap: 16px;
|
|
449
|
+
padding: 16px 0;
|
|
450
|
+
background: var(--pp-surface);
|
|
451
|
+
}
|
|
452
|
+
.pp-home-item {
|
|
453
|
+
box-sizing: border-box;
|
|
454
|
+
display: flex;
|
|
455
|
+
flex-direction: column;
|
|
456
|
+
align-items: center;
|
|
457
|
+
width: 25%;
|
|
458
|
+
min-width: 0;
|
|
459
|
+
padding: 0 4px;
|
|
460
|
+
border: 0;
|
|
461
|
+
background: none;
|
|
462
|
+
color: var(--pp-text);
|
|
463
|
+
font:
|
|
464
|
+
12px / 1.5 -apple-system,
|
|
465
|
+
sans-serif;
|
|
466
|
+
cursor: pointer;
|
|
467
|
+
text-decoration: none;
|
|
468
|
+
}
|
|
469
|
+
@media (min-width: 500px) {
|
|
470
|
+
.pp-home-item {
|
|
471
|
+
width: calc(100% / 6);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
@media (min-width: 700px) {
|
|
475
|
+
.pp-home-item {
|
|
476
|
+
width: 12.5%;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
.pp-home-icon {
|
|
480
|
+
box-sizing: border-box;
|
|
481
|
+
width: 56px;
|
|
482
|
+
height: 56px;
|
|
483
|
+
padding: 8px;
|
|
484
|
+
border-radius: 50%;
|
|
485
|
+
background: var(--pp-field);
|
|
486
|
+
font-size: 32px;
|
|
487
|
+
line-height: 40px;
|
|
488
|
+
}
|
|
489
|
+
.pp-home-icon img {
|
|
490
|
+
display: block;
|
|
491
|
+
width: 100%;
|
|
492
|
+
height: 100%;
|
|
493
|
+
object-fit: contain;
|
|
494
|
+
}
|
|
495
|
+
.pp-home-name {
|
|
496
|
+
margin-top: 8px;
|
|
497
|
+
}
|
|
498
|
+
.pp-home-content {
|
|
499
|
+
min-width: 0;
|
|
500
|
+
width: 100%;
|
|
501
|
+
}
|
|
502
|
+
.pp-home-content > span {
|
|
503
|
+
display: block;
|
|
504
|
+
}
|
|
505
|
+
.pp-home-name,
|
|
506
|
+
.pp-home-item [data-module-status] {
|
|
507
|
+
width: 100%;
|
|
508
|
+
overflow: hidden;
|
|
509
|
+
text-align: center;
|
|
510
|
+
text-overflow: ellipsis;
|
|
511
|
+
white-space: nowrap;
|
|
512
|
+
}
|
|
513
|
+
.pp-home-item [data-module-status] {
|
|
514
|
+
min-height: 20px;
|
|
515
|
+
}
|
|
516
|
+
.pp-home-item:disabled {
|
|
517
|
+
opacity: 0.45;
|
|
518
|
+
cursor: default;
|
|
519
|
+
}
|
|
520
|
+
.pp-home-entries[data-layout="list"] {
|
|
521
|
+
display: block;
|
|
522
|
+
padding: 0;
|
|
523
|
+
}
|
|
524
|
+
.pp-home-entries[data-layout="list"] .pp-home-item {
|
|
525
|
+
flex-direction: row;
|
|
526
|
+
gap: 12px;
|
|
527
|
+
width: 100%;
|
|
528
|
+
padding: 12px 16px;
|
|
529
|
+
font-size: 15px;
|
|
530
|
+
}
|
|
531
|
+
.pp-home-entries[data-layout="list"] .pp-home-item + .pp-home-item {
|
|
532
|
+
border-top: 1px solid var(--pp-border);
|
|
533
|
+
}
|
|
534
|
+
.pp-home-entries[data-layout="list"] .pp-home-icon {
|
|
535
|
+
flex: none;
|
|
536
|
+
width: 40px;
|
|
537
|
+
height: 40px;
|
|
538
|
+
padding: 4px;
|
|
539
|
+
font-size: 24px;
|
|
540
|
+
line-height: 32px;
|
|
541
|
+
}
|
|
542
|
+
.pp-home-entries[data-layout="list"] .pp-home-name {
|
|
543
|
+
margin-top: 0;
|
|
544
|
+
text-align: left;
|
|
545
|
+
}
|
|
546
|
+
.pp-home-arrow {
|
|
547
|
+
color: var(--pp-muted);
|
|
548
|
+
font-size: 24px;
|
|
549
|
+
}
|
|
550
|
+
.pp-home-footer {
|
|
551
|
+
margin-top: 16px;
|
|
552
|
+
text-align: center;
|
|
553
|
+
white-space: normal;
|
|
554
|
+
}
|
|
555
|
+
.pp-home-footer p {
|
|
556
|
+
margin: 8px 0 0;
|
|
557
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -123,6 +123,10 @@ export interface SettingsResponse {
|
|
|
123
123
|
* Fields, storage root and optional display metadata belonging to one module.
|
|
124
124
|
*/
|
|
125
125
|
export interface ModuleDefinition {
|
|
126
|
+
/** 页面重置的完整设置路径,默认删除当前模块数据 / Complete setting paths reset by the page; defaults to deleting this module's data. */
|
|
127
|
+
resetPaths?: string[];
|
|
128
|
+
/** 同一存储根中的完整缓存路径,默认当前模块 Caches / Complete cache path in the same storage root, defaulting to this module's Caches. */
|
|
129
|
+
cachePath?: string;
|
|
126
130
|
/**
|
|
127
131
|
* 字段 ID 的模块段,不能由 app 名称推断
|
|
128
132
|
* Module segment from field IDs, never inferred from app names.
|
|
@@ -246,6 +250,10 @@ export interface BoxJSSetting {
|
|
|
246
250
|
* A BoxJS application.
|
|
247
251
|
*/
|
|
248
252
|
export interface BoxJSApp extends BoxJSMetadata {
|
|
253
|
+
/** 共享模块存储时,限定本页面可重置的设置路径 / Limit reset paths when multiple pages share module storage. */
|
|
254
|
+
resetPaths?: string[];
|
|
255
|
+
/** 可选共享缓存路径,例如 @Root.Composite.Caches / Optional shared cache path, such as @Root.Composite.Caches. */
|
|
256
|
+
cachePath?: string;
|
|
249
257
|
/**
|
|
250
258
|
* 应用设置
|
|
251
259
|
* Application settings.
|