@geekity/cms 0.23.0 → 0.25.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/README.md +96 -160
- package/admin/pages/documents/editor.njk +45 -0
- package/admin/pages/federation/settings.njk +1 -59
- package/admin/pages/plugins/installed.njk +113 -0
- package/admin/pages/plugins/screen.njk +129 -0
- package/admin/static/admin.css +136 -4
- package/admin/static/editor-actions.js +192 -0
- package/admin/static/editor.js +1 -1
- package/dist/admin/accounts.d.ts +18 -39
- package/dist/admin/accounts.d.ts.map +1 -1
- package/dist/admin/accounts.js +19 -48
- package/dist/admin/accounts.js.map +1 -1
- package/dist/admin/documents.d.ts +5 -0
- package/dist/admin/documents.d.ts.map +1 -1
- package/dist/admin/documents.js +17 -8
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/editor-actions.d.ts +35 -0
- package/dist/admin/editor-actions.d.ts.map +1 -0
- package/dist/admin/editor-actions.js +168 -0
- package/dist/admin/editor-actions.js.map +1 -0
- package/dist/admin/federation.d.ts +4 -5
- package/dist/admin/federation.d.ts.map +1 -1
- package/dist/admin/federation.js +4 -5
- package/dist/admin/federation.js.map +1 -1
- package/dist/admin/index.d.ts +1 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/menu.d.ts +1 -1
- package/dist/admin/menu.d.ts.map +1 -1
- package/dist/admin/menu.js +10 -3
- package/dist/admin/menu.js.map +1 -1
- package/dist/admin/plugins.d.ts +24 -0
- package/dist/admin/plugins.d.ts.map +1 -0
- package/dist/admin/plugins.js +312 -0
- package/dist/admin/plugins.js.map +1 -0
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +5 -1
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/settings-federation.d.ts +0 -25
- package/dist/admin/settings-federation.d.ts.map +1 -1
- package/dist/admin/settings-federation.js +1 -54
- package/dist/admin/settings-federation.js.map +1 -1
- package/dist/admin/settings.d.ts +2 -14
- package/dist/admin/settings.d.ts.map +1 -1
- package/dist/admin/settings.js +1 -21
- package/dist/admin/settings.js.map +1 -1
- package/dist/admin/store.d.ts +8 -1
- package/dist/admin/store.d.ts.map +1 -1
- package/dist/admin/store.js +7 -3
- package/dist/admin/store.js.map +1 -1
- package/dist/admin/templates.d.ts +2 -0
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +2 -0
- package/dist/admin/templates.js.map +1 -1
- package/dist/cli.d.ts +2 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +278 -212
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/content/store.d.ts +6 -0
- package/dist/content/store.d.ts.map +1 -1
- package/dist/content/store.js +3 -0
- package/dist/content/store.js.map +1 -1
- package/dist/drain.d.ts +28 -0
- package/dist/drain.d.ts.map +1 -0
- package/dist/drain.js +106 -0
- package/dist/drain.js.map +1 -0
- package/dist/env.d.ts +11 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/federation/federation.d.ts +4 -2
- package/dist/federation/federation.d.ts.map +1 -1
- package/dist/federation/federation.js +16 -21
- package/dist/federation/federation.js.map +1 -1
- package/dist/federation/inbox.d.ts +23 -3
- package/dist/federation/inbox.d.ts.map +1 -1
- package/dist/federation/inbox.js +63 -1
- package/dist/federation/inbox.js.map +1 -1
- package/dist/federation/index.d.ts +0 -4
- package/dist/federation/index.d.ts.map +1 -1
- package/dist/federation/index.js +0 -2
- package/dist/federation/index.js.map +1 -1
- package/dist/federation/mount.d.ts +6 -12
- package/dist/federation/mount.d.ts.map +1 -1
- package/dist/federation/mount.js +3 -50
- package/dist/federation/mount.js.map +1 -1
- package/dist/federation/queue.d.ts +22 -0
- package/dist/federation/queue.d.ts.map +1 -0
- package/dist/federation/queue.js +58 -0
- package/dist/federation/queue.js.map +1 -0
- package/dist/files/atomic.d.ts +13 -0
- package/dist/files/atomic.d.ts.map +1 -1
- package/dist/files/atomic.js +45 -0
- package/dist/files/atomic.js.map +1 -1
- package/dist/index.d.ts +30 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -79
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +513 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +23 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/enabled.d.ts +23 -0
- package/dist/plugins/enabled.d.ts.map +1 -0
- package/dist/plugins/enabled.js +49 -0
- package/dist/plugins/enabled.js.map +1 -0
- package/dist/plugins/federation.d.ts +26 -0
- package/dist/plugins/federation.d.ts.map +1 -0
- package/dist/plugins/federation.js +114 -0
- package/dist/plugins/federation.js.map +1 -0
- package/dist/plugins/fetch.d.ts +15 -0
- package/dist/plugins/fetch.d.ts.map +1 -0
- package/dist/plugins/fetch.js +33 -0
- package/dist/plugins/fetch.js.map +1 -0
- package/dist/plugins/folder.d.ts +50 -0
- package/dist/plugins/folder.d.ts.map +1 -0
- package/dist/plugins/folder.js +171 -0
- package/dist/plugins/folder.js.map +1 -0
- package/dist/plugins/install.d.ts +45 -0
- package/dist/plugins/install.d.ts.map +1 -0
- package/dist/plugins/install.js +275 -0
- package/dist/plugins/install.js.map +1 -0
- package/dist/plugins/mount.d.ts +17 -0
- package/dist/plugins/mount.d.ts.map +1 -0
- package/dist/plugins/mount.js +44 -0
- package/dist/plugins/mount.js.map +1 -0
- package/dist/plugins/registry.d.ts +110 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +447 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/settings.d.ts +64 -0
- package/dist/plugins/settings.d.ts.map +1 -0
- package/dist/plugins/settings.js +219 -0
- package/dist/plugins/settings.js.map +1 -0
- package/dist/plugins/site.d.ts +17 -0
- package/dist/plugins/site.d.ts.map +1 -0
- package/dist/plugins/site.js +67 -0
- package/dist/plugins/site.js.map +1 -0
- package/dist/supervisor/primary.d.ts +47 -0
- package/dist/supervisor/primary.d.ts.map +1 -0
- package/dist/supervisor/primary.js +208 -0
- package/dist/supervisor/primary.js.map +1 -0
- package/dist/supervisor/protocol.d.ts +37 -0
- package/dist/supervisor/protocol.d.ts.map +1 -0
- package/dist/supervisor/protocol.js +29 -0
- package/dist/supervisor/protocol.js.map +1 -0
- package/dist/supervisor/supervision.d.ts +25 -0
- package/dist/supervisor/supervision.d.ts.map +1 -0
- package/dist/supervisor/supervision.js +7 -0
- package/dist/supervisor/supervision.js.map +1 -0
- package/dist/supervisor/worker.d.ts +29 -0
- package/dist/supervisor/worker.d.ts.map +1 -0
- package/dist/supervisor/worker.js +97 -0
- package/dist/supervisor/worker.js.map +1 -0
- package/dist/web/errors.d.ts.map +1 -1
- package/dist/web/errors.js +5 -3
- package/dist/web/errors.js.map +1 -1
- package/dist/web/llms.d.ts +8 -0
- package/dist/web/llms.d.ts.map +1 -1
- package/dist/web/llms.js +25 -7
- package/dist/web/llms.js.map +1 -1
- package/dist/web/maintenance.d.ts +2 -2
- package/dist/web/maintenance.d.ts.map +1 -1
- package/dist/web/maintenance.js +7 -4
- package/dist/web/maintenance.js.map +1 -1
- package/dist/web/negotiate.d.ts +8 -5
- package/dist/web/negotiate.d.ts.map +1 -1
- package/dist/web/negotiate.js +21 -10
- package/dist/web/negotiate.js.map +1 -1
- package/dist/web/routes.d.ts.map +1 -1
- package/dist/web/routes.js +84 -36
- package/dist/web/routes.js.map +1 -1
- package/package.json +11 -5
- package/dist/comments/conversation.d.ts +0 -29
- package/dist/comments/conversation.d.ts.map +0 -1
- package/dist/comments/conversation.js +0 -60
- package/dist/comments/conversation.js.map +0 -1
- package/dist/federation/import-wordpress.d.ts +0 -128
- package/dist/federation/import-wordpress.d.ts.map +0 -1
- package/dist/federation/import-wordpress.js +0 -426
- package/dist/federation/import-wordpress.js.map +0 -1
- package/dist/federation/wordpress.d.ts +0 -131
- package/dist/federation/wordpress.d.ts.map +0 -1
- package/dist/federation/wordpress.js +0 -342
- package/dist/federation/wordpress.js.map +0 -1
- package/dist/web/comments.d.ts +0 -60
- package/dist/web/comments.d.ts.map +0 -1
- package/dist/web/comments.js +0 -207
- package/dist/web/comments.js.map +0 -1
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
{# /admin/plugins/<package name>: a plugin's own screen (decision-33). The
|
|
2
|
+
plugin hands over cards of paragraphs and tables as data and this draws
|
|
3
|
+
them, so a plugin writes no markup and everything it says is escaped.
|
|
4
|
+
|
|
5
|
+
A plugin with settings gets a form here too (TASK-283). A label or hint
|
|
6
|
+
from a plugin is escaped before the field macros, which print theirs as
|
|
7
|
+
markup. A secret is never printed: the form says whether it is set and
|
|
8
|
+
where, and names the environment variable that would set it. #}
|
|
9
|
+
{% extends "layouts/shell.njk" %}
|
|
10
|
+
{% import "components/fields.njk" as field %}
|
|
11
|
+
{% from "components/badge.njk" import status %}
|
|
12
|
+
{% from "components/button.njk" import button %}
|
|
13
|
+
{% from "components/card.njk" import card, cardActions %}
|
|
14
|
+
{% from "components/table.njk" import table %}
|
|
15
|
+
|
|
16
|
+
{% macro text(parts) -%}
|
|
17
|
+
{%- for part in parts -%}
|
|
18
|
+
{%- if part.code is defined -%}<code>{{ part.code }}</code>{%- else -%}{{ part }}{%- endif -%}
|
|
19
|
+
{%- endfor -%}
|
|
20
|
+
{%- endmacro %}
|
|
21
|
+
|
|
22
|
+
{% block title %}{{ title }}{% endblock %}
|
|
23
|
+
|
|
24
|
+
{% block content %}
|
|
25
|
+
<h1 class="mb-6 text-2xl font-bold">{{ title }}</h1>
|
|
26
|
+
|
|
27
|
+
{% if problems.length %}
|
|
28
|
+
{% call field.summary('Nothing was saved. Fix the fields marked below.') %}
|
|
29
|
+
{% for setting in problems %}{{ field.problem(setting.id, setting.error) }}{% endfor %}
|
|
30
|
+
{% endcall %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
<div class="grid max-w-5xl grid-cols-1 gap-6">
|
|
34
|
+
{% if settings.length or actions.length %}
|
|
35
|
+
{% call card(title='Settings' if settings.length else 'Actions') %}
|
|
36
|
+
{% if settings.length %}
|
|
37
|
+
<form method="post" action="{{ postUrl }}">
|
|
38
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
39
|
+
<input type="hidden" name="{{ actionField }}" value="{{ saveAction }}" />
|
|
40
|
+
{% for setting in settings %}
|
|
41
|
+
{% set label = setting.label | escape %}
|
|
42
|
+
{% set error = setting.error or setting.stored %}
|
|
43
|
+
{% if setting.type == 'secret' %}
|
|
44
|
+
{% set hint %}{% if setting.hint %}{{ setting.hint }} {% endif %}{% if setting.source == 'environment' %}Set by the environment variable <code>{{ setting.variable }}</code>. Change it there.{% elif setting.source == 'file' %}Set in <code>{{ secretsFile }}</code>. Leave the box blank to keep it. The environment variable <code>{{ setting.variable }}</code> would win over it.{% else %}Not set. Or set the environment variable <code>{{ setting.variable }}</code>.{% endif %}{% endset %}
|
|
45
|
+
{% if setting.source == 'environment' %}
|
|
46
|
+
<div class="fieldset">
|
|
47
|
+
<p class="fieldset-legend">{{ label }} {{ status('connected', 'Set') }}</p>
|
|
48
|
+
<p class="label block whitespace-normal">{{ hint | safe }}</p>
|
|
49
|
+
</div>
|
|
50
|
+
{% else %}
|
|
51
|
+
{{ field.password(setting.id, setting.name,
|
|
52
|
+
label ~ ' ' ~ (status('connected', 'Set') if setting.source == 'file' else status('missing', 'Not set')),
|
|
53
|
+
hint=hint, error=setting.error, autocomplete='off', spellcheck='false',
|
|
54
|
+
placeholder=('Leave blank to keep it' if setting.source == 'file' else '')) }}
|
|
55
|
+
{% if setting.source == 'file' %}
|
|
56
|
+
{{ field.checkbox(setting.id ~ '-forget', setting.forgetName, 'Forget the stored ' ~ label) }}
|
|
57
|
+
{% endif %}
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% else %}
|
|
60
|
+
{% set hint %}{{ setting.hint }}{% endset %}
|
|
61
|
+
{% if setting.type == 'checkbox' %}
|
|
62
|
+
{{ field.checkbox(setting.id, setting.name, label, checked=setting.checked,
|
|
63
|
+
hint=hint, error=error) }}
|
|
64
|
+
{% elif setting.type == 'select' %}
|
|
65
|
+
{% call field.select(setting.id, setting.name, label, hint=hint, error=error) %}
|
|
66
|
+
{% for option in setting.options %}
|
|
67
|
+
<option value="{{ option.value }}"{% if option.selected %} selected{% endif %}>{{ option.label }}</option>
|
|
68
|
+
{% endfor %}
|
|
69
|
+
{% endcall %}
|
|
70
|
+
{% else %}
|
|
71
|
+
{{ field.text(setting.id, setting.name, label, setting.value, hint=hint, error=error,
|
|
72
|
+
inputmode=('url' if setting.type == 'url' else ''), spellcheck='false') }}
|
|
73
|
+
{% endif %}
|
|
74
|
+
{% endif %}
|
|
75
|
+
{% endfor %}
|
|
76
|
+
<div class="mt-2">{{ button('Save settings', type='submit', color='primary') }}</div>
|
|
77
|
+
</form>
|
|
78
|
+
{% endif %}
|
|
79
|
+
|
|
80
|
+
{% for action in actions %}
|
|
81
|
+
<form method="post" action="{{ postUrl }}">
|
|
82
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
83
|
+
<input type="hidden" name="{{ actionField }}" value="{{ action.id }}" />
|
|
84
|
+
{{ button(action.label, type='submit') }}
|
|
85
|
+
</form>
|
|
86
|
+
{% endfor %}
|
|
87
|
+
|
|
88
|
+
{% if settings.length %}
|
|
89
|
+
<p class="text-sm">
|
|
90
|
+
Settings other than secrets are kept under this plugin's key in
|
|
91
|
+
<code>content/_data/site.json</code>. Secrets are kept in
|
|
92
|
+
<code>{{ secretsFile }}</code> at mode <code>0600</code> and are never shown here.
|
|
93
|
+
</p>
|
|
94
|
+
{% endif %}
|
|
95
|
+
{% endcall %}
|
|
96
|
+
{% endif %}
|
|
97
|
+
|
|
98
|
+
{% for entry in cards %}
|
|
99
|
+
{% call card(title=entry.title) %}
|
|
100
|
+
{% for block in entry.blocks %}
|
|
101
|
+
{% if block.table %}
|
|
102
|
+
{% call table(block.table.caption, inCard=true) %}
|
|
103
|
+
<thead>
|
|
104
|
+
<tr>
|
|
105
|
+
{% for column in block.table.columns %}<th scope="col">{{ column }}</th>{% endfor %}
|
|
106
|
+
</tr>
|
|
107
|
+
</thead>
|
|
108
|
+
<tbody>
|
|
109
|
+
{% for row in block.table.rows %}
|
|
110
|
+
<tr>
|
|
111
|
+
{% for cell in row %}
|
|
112
|
+
{% if cell.time is defined %}
|
|
113
|
+
<td class="whitespace-nowrap">{% if cell.time %}{{ cell.time | date('readable') }}{% else %}Never{% endif %}</td>
|
|
114
|
+
{% else %}
|
|
115
|
+
<td>{{ text([cell]) }}</td>
|
|
116
|
+
{% endif %}
|
|
117
|
+
{% endfor %}
|
|
118
|
+
</tr>
|
|
119
|
+
{% endfor %}
|
|
120
|
+
</tbody>
|
|
121
|
+
{% endcall %}
|
|
122
|
+
{% else %}
|
|
123
|
+
<p class="text-sm">{{ text(block.paragraph) }}</p>
|
|
124
|
+
{% endif %}
|
|
125
|
+
{% endfor %}
|
|
126
|
+
{% endcall %}
|
|
127
|
+
{% endfor %}
|
|
128
|
+
</div>
|
|
129
|
+
{% endblock %}
|
package/admin/static/admin.css
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
--container-md: 28rem;
|
|
45
45
|
--container-2xl: 42rem;
|
|
46
46
|
--container-3xl: 48rem;
|
|
47
|
+
--container-5xl: 64rem;
|
|
47
48
|
--text-xs: .75rem;
|
|
48
49
|
--text-xs--line-height: calc(1 / .75);
|
|
49
50
|
--text-sm: .875rem;
|
|
@@ -1572,11 +1573,122 @@
|
|
|
1572
1573
|
@layer components;
|
|
1573
1574
|
|
|
1574
1575
|
@layer utilities {
|
|
1575
|
-
.\@container {
|
|
1576
|
-
container-type: inline-size;
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
1576
|
@layer daisyui.l1.l2.l3 {
|
|
1577
|
+
.range {
|
|
1578
|
+
appearance: none;
|
|
1579
|
+
webkit-appearance: none;
|
|
1580
|
+
--range-thumb: var(--color-base-100);
|
|
1581
|
+
--range-thumb-size: calc(var(--size-selector, .25rem) * 6);
|
|
1582
|
+
--range-progress: currentColor;
|
|
1583
|
+
--range-fill: 1;
|
|
1584
|
+
--range-p: .25rem;
|
|
1585
|
+
--range-bg: currentColor;
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1589
|
+
.range {
|
|
1590
|
+
--range-bg: color-mix(in oklab, currentColor 10%, #0000);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
.range {
|
|
1595
|
+
--range-fill-x: calc((var(--range-dir, 1) * -100cqw) - (var(--range-dir, 1) * var(--range-thumb-size) / 2));
|
|
1596
|
+
--range-fill-y: 0;
|
|
1597
|
+
--range-fill-spread: calc(100cqw * var(--range-fill));
|
|
1598
|
+
cursor: pointer;
|
|
1599
|
+
vertical-align: middle;
|
|
1600
|
+
--radius-selector-max: calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));
|
|
1601
|
+
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
|
1602
|
+
width: clamp(3rem, 20rem, 100%);
|
|
1603
|
+
height: var(--range-thumb-size);
|
|
1604
|
+
background-color: #0000;
|
|
1605
|
+
border: none;
|
|
1606
|
+
overflow: hidden;
|
|
1607
|
+
container-type: inline-size;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
[dir="rtl"] .range {
|
|
1611
|
+
--range-dir: -1;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
.range:focus {
|
|
1615
|
+
outline: none;
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
.range:focus-visible {
|
|
1619
|
+
outline-offset: 2px;
|
|
1620
|
+
outline: 2px solid;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
.range::-webkit-slider-runnable-track {
|
|
1624
|
+
background-color: var(--range-bg);
|
|
1625
|
+
border-radius: var(--radius-selector);
|
|
1626
|
+
width: 100%;
|
|
1627
|
+
height: calc(var(--range-thumb-size) * .5);
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
@media (forced-colors: active) {
|
|
1631
|
+
.range::-webkit-slider-runnable-track {
|
|
1632
|
+
border: 1px solid;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
.range::-moz-range-track {
|
|
1636
|
+
border: 1px solid;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
.range::-moz-range-track {
|
|
1641
|
+
background-color: var(--range-bg);
|
|
1642
|
+
border-radius: var(--radius-selector);
|
|
1643
|
+
width: 100%;
|
|
1644
|
+
height: calc(var(--range-thumb-size) * .5);
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
.range::-webkit-slider-thumb {
|
|
1648
|
+
box-sizing: border-box;
|
|
1649
|
+
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
|
1650
|
+
background-color: var(--range-thumb);
|
|
1651
|
+
height: var(--range-thumb-size);
|
|
1652
|
+
width: var(--range-thumb-size);
|
|
1653
|
+
border: var(--range-p) solid;
|
|
1654
|
+
appearance: none;
|
|
1655
|
+
webkit-appearance: none;
|
|
1656
|
+
color: var(--range-progress);
|
|
1657
|
+
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
|
1658
|
+
position: relative;
|
|
1659
|
+
inset-block-start: 50%;
|
|
1660
|
+
transform: translateY(-50%);
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1664
|
+
.range::-webkit-slider-thumb {
|
|
1665
|
+
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
.range::-moz-range-thumb {
|
|
1670
|
+
box-sizing: border-box;
|
|
1671
|
+
border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max)));
|
|
1672
|
+
height: var(--range-thumb-size);
|
|
1673
|
+
width: var(--range-thumb-size);
|
|
1674
|
+
border: var(--range-p) solid;
|
|
1675
|
+
color: var(--range-progress);
|
|
1676
|
+
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
|
1677
|
+
background-color: currentColor;
|
|
1678
|
+
position: relative;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1682
|
+
.range::-moz-range-thumb {
|
|
1683
|
+
box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * .1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * .1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, var(--range-fill-x) var(--range-fill-y) 0 var(--range-fill-spread);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
.range:disabled {
|
|
1688
|
+
cursor: not-allowed;
|
|
1689
|
+
opacity: .3;
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1580
1692
|
:where(.drawer-side) {
|
|
1581
1693
|
overflow: hidden;
|
|
1582
1694
|
}
|
|
@@ -4257,6 +4369,10 @@
|
|
|
4257
4369
|
}
|
|
4258
4370
|
}
|
|
4259
4371
|
|
|
4372
|
+
.\@container {
|
|
4373
|
+
container-type: inline-size;
|
|
4374
|
+
}
|
|
4375
|
+
|
|
4260
4376
|
@layer daisyui.l1.l2 {
|
|
4261
4377
|
.drawer-open > .drawer-side {
|
|
4262
4378
|
overflow-y: auto;
|
|
@@ -6432,6 +6548,10 @@
|
|
|
6432
6548
|
margin-top: calc(var(--spacing) * -1);
|
|
6433
6549
|
}
|
|
6434
6550
|
|
|
6551
|
+
.mt-0\.5 {
|
|
6552
|
+
margin-top: calc(var(--spacing) * .5);
|
|
6553
|
+
}
|
|
6554
|
+
|
|
6435
6555
|
.mt-1 {
|
|
6436
6556
|
margin-top: var(--spacing);
|
|
6437
6557
|
}
|
|
@@ -6583,6 +6703,10 @@
|
|
|
6583
6703
|
max-width: var(--container-3xl);
|
|
6584
6704
|
}
|
|
6585
6705
|
|
|
6706
|
+
.max-w-5xl {
|
|
6707
|
+
max-width: var(--container-5xl);
|
|
6708
|
+
}
|
|
6709
|
+
|
|
6586
6710
|
.max-w-full {
|
|
6587
6711
|
max-width: 100%;
|
|
6588
6712
|
}
|
|
@@ -6884,6 +7008,10 @@
|
|
|
6884
7008
|
white-space: pre-line;
|
|
6885
7009
|
}
|
|
6886
7010
|
|
|
7011
|
+
.whitespace-pre-wrap {
|
|
7012
|
+
white-space: pre-wrap;
|
|
7013
|
+
}
|
|
7014
|
+
|
|
6887
7015
|
.text-base-content, .text-base-content\/70 {
|
|
6888
7016
|
color: var(--color-base-content);
|
|
6889
7017
|
}
|
|
@@ -7261,6 +7389,10 @@
|
|
|
7261
7389
|
}
|
|
7262
7390
|
|
|
7263
7391
|
@media (min-width: 80rem) {
|
|
7392
|
+
.xl\:grid-cols-2 {
|
|
7393
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
7394
|
+
}
|
|
7395
|
+
|
|
7264
7396
|
.xl\:grid-cols-\[minmax\(0\,1fr\)_20rem\] {
|
|
7265
7397
|
grid-template-columns: minmax(0, 1fr) 20rem;
|
|
7266
7398
|
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/* The buttons running plugins put beside the editor's title, description and
|
|
2
|
+
tags (decision-33). Each posts the form as it stands to its plugin's
|
|
3
|
+
endpoint, which answers { ok, value }, { ok, choices } or { ok: false,
|
|
4
|
+
message }, and shows the suggestion with Accept and Dismiss. Choices come
|
|
5
|
+
only beside the tags field, each drawn from the page's template row with a
|
|
6
|
+
box to tick, and Accept adds the ticked ones. Accept fills the field and saves
|
|
7
|
+
nothing; a save is still only the form's own buttons.
|
|
8
|
+
|
|
9
|
+
A file rather than an inline script, loaded from the admin's own origin
|
|
10
|
+
like slug.js, so the admin's policy stays `script-src 'self'` and
|
|
11
|
+
`connect-src 'self'`. Plain ES5-shaped browser JavaScript, served as it is
|
|
12
|
+
written. */
|
|
13
|
+
(function () {
|
|
14
|
+
function plainForm(form) {
|
|
15
|
+
var fields = new URLSearchParams();
|
|
16
|
+
new FormData(form).forEach(function (value, name) {
|
|
17
|
+
if (typeof value === 'string') fields.append(name, value);
|
|
18
|
+
});
|
|
19
|
+
return fields;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function tagsOf(value) {
|
|
23
|
+
return value
|
|
24
|
+
.split(',')
|
|
25
|
+
.map(function (tag) {
|
|
26
|
+
return tag.trim();
|
|
27
|
+
})
|
|
28
|
+
.filter(function (tag) {
|
|
29
|
+
return tag !== '';
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* A tags suggestion adds what the field does not already hold; a title or
|
|
34
|
+
description suggestion replaces the field. */
|
|
35
|
+
function accepted(field, value) {
|
|
36
|
+
if (field.id !== 'editor-tags') return value;
|
|
37
|
+
var held = tagsOf(field.value);
|
|
38
|
+
var known = held.map(function (tag) {
|
|
39
|
+
return tag.toLowerCase();
|
|
40
|
+
});
|
|
41
|
+
tagsOf(value).forEach(function (tag) {
|
|
42
|
+
if (known.indexOf(tag.toLowerCase()) === -1) {
|
|
43
|
+
held.push(tag);
|
|
44
|
+
known.push(tag.toLowerCase());
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return held.join(', ');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function enhance(block, field) {
|
|
51
|
+
var url = block.getAttribute('data-editor-action');
|
|
52
|
+
var press = block.querySelector('button');
|
|
53
|
+
var status = block.querySelector('[role="status"]');
|
|
54
|
+
var suggestion = block.querySelector('[role="group"]');
|
|
55
|
+
var text = suggestion && suggestion.querySelector('p');
|
|
56
|
+
var list = suggestion && suggestion.querySelector('[data-editor-choices]');
|
|
57
|
+
var row = block.querySelector('template[data-editor-choice]');
|
|
58
|
+
if (!url || !press || !status || !text || !list || !row) return;
|
|
59
|
+
var buttons = suggestion.querySelectorAll('button');
|
|
60
|
+
var accept = buttons[0];
|
|
61
|
+
var dismiss = buttons[1];
|
|
62
|
+
var pending = null;
|
|
63
|
+
var offered = '';
|
|
64
|
+
|
|
65
|
+
function say(message, failed) {
|
|
66
|
+
status.textContent = message;
|
|
67
|
+
status.classList.toggle('text-error', failed === true);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function close() {
|
|
71
|
+
suggestion.hidden = true;
|
|
72
|
+
offered = '';
|
|
73
|
+
list.replaceChildren();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function drawChoices(choices) {
|
|
77
|
+
choices.forEach(function (choice) {
|
|
78
|
+
var item = row.content.firstElementChild.cloneNode(true);
|
|
79
|
+
var badge = item.querySelector('.badge');
|
|
80
|
+
item.querySelector('input').value = String(choice.value);
|
|
81
|
+
item.querySelector('[data-choice-value]').textContent = String(choice.value);
|
|
82
|
+
badge.textContent = choice.badge ? String(choice.badge) : '';
|
|
83
|
+
badge.hidden = !choice.badge;
|
|
84
|
+
item.querySelector('[data-choice-note]').textContent = choice.note
|
|
85
|
+
? String(choice.note)
|
|
86
|
+
: '';
|
|
87
|
+
list.appendChild(item);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function ticked() {
|
|
92
|
+
var values = [];
|
|
93
|
+
list.querySelectorAll('input:checked').forEach(function (box) {
|
|
94
|
+
values.push(box.value);
|
|
95
|
+
});
|
|
96
|
+
return values.join(', ');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
press.hidden = false;
|
|
100
|
+
press.addEventListener('click', function () {
|
|
101
|
+
if (pending) pending.abort();
|
|
102
|
+
var controller = new AbortController();
|
|
103
|
+
pending = controller;
|
|
104
|
+
close();
|
|
105
|
+
press.disabled = true;
|
|
106
|
+
say('Asking for a suggestion…');
|
|
107
|
+
|
|
108
|
+
fetch(url, {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
body: plainForm(field.form),
|
|
111
|
+
credentials: 'same-origin',
|
|
112
|
+
headers: { accept: 'application/json' },
|
|
113
|
+
signal: controller.signal,
|
|
114
|
+
})
|
|
115
|
+
.then(function (response) {
|
|
116
|
+
var type = response.headers.get('content-type') || '';
|
|
117
|
+
if (type.indexOf('application/json') === -1) {
|
|
118
|
+
throw new Error(
|
|
119
|
+
response.status === 403
|
|
120
|
+
? 'The site refused the request because this page is out of date. Copy your changes somewhere safe, then reload the page.'
|
|
121
|
+
: response.redirected
|
|
122
|
+
? 'You are signed out. Sign in again in another tab, then try again.'
|
|
123
|
+
: 'The site answered ' + response.status + ' instead of a suggestion.',
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return response.json();
|
|
127
|
+
})
|
|
128
|
+
.then(function (answer) {
|
|
129
|
+
if (answer.ok && Array.isArray(answer.choices)) {
|
|
130
|
+
if (answer.choices.length === 0) {
|
|
131
|
+
say('There was nothing to suggest.');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
text.hidden = true;
|
|
135
|
+
drawChoices(answer.choices);
|
|
136
|
+
list.hidden = false;
|
|
137
|
+
suggestion.hidden = false;
|
|
138
|
+
say('');
|
|
139
|
+
list.querySelector('input').focus();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (answer.ok) {
|
|
143
|
+
offered = String(answer.value);
|
|
144
|
+
text.textContent = offered;
|
|
145
|
+
text.hidden = false;
|
|
146
|
+
list.hidden = true;
|
|
147
|
+
suggestion.hidden = false;
|
|
148
|
+
say('');
|
|
149
|
+
accept.focus();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
say(String(answer.message), true);
|
|
153
|
+
if (answer.withdrawn) press.hidden = true;
|
|
154
|
+
})
|
|
155
|
+
.catch(function (error) {
|
|
156
|
+
if (controller.signal.aborted) return;
|
|
157
|
+
say(
|
|
158
|
+
error instanceof TypeError
|
|
159
|
+
? 'The site could not be reached. Check the connection and try again.'
|
|
160
|
+
: error.message,
|
|
161
|
+
true,
|
|
162
|
+
);
|
|
163
|
+
})
|
|
164
|
+
.then(function () {
|
|
165
|
+
if (pending === controller) pending = null;
|
|
166
|
+
press.disabled = false;
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
accept.addEventListener('click', function () {
|
|
171
|
+
field.value = accepted(field, list.hidden ? offered : ticked());
|
|
172
|
+
field.dispatchEvent(new Event('input', { bubbles: true }));
|
|
173
|
+
close();
|
|
174
|
+
say('');
|
|
175
|
+
field.focus();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
dismiss.addEventListener('click', function () {
|
|
179
|
+
close();
|
|
180
|
+
say('');
|
|
181
|
+
press.focus();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var groups = document.querySelectorAll('[data-editor-actions]');
|
|
186
|
+
for (var i = 0; i < groups.length; i++) {
|
|
187
|
+
var field = document.getElementById(groups[i].getAttribute('data-editor-actions'));
|
|
188
|
+
if (!field || !field.form) continue;
|
|
189
|
+
var blocks = groups[i].querySelectorAll('[data-editor-action]');
|
|
190
|
+
for (var j = 0; j < blocks.length; j++) enhance(blocks[j], field);
|
|
191
|
+
}
|
|
192
|
+
})();
|