domma-cms 1.10.38 → 1.11.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 +10 -0
- package/admin/js/lib/menu-editor-arrange.js +2 -2
- package/admin/js/lib/menu-rows.js +1 -1
- package/admin/js/lib/shortcode-registry.js +3 -3
- package/admin/js/lib/site-settings-arrange.js +3 -1
- package/admin/js/templates/docs/usage-navigation.html +36 -1
- package/admin/js/templates/docs/usage-shortcodes.html +26 -1
- package/admin/js/templates/docs/usage-site-settings.html +23 -2
- package/admin/js/templates/menu-editor.html +31 -0
- package/admin/js/templates/settings.html +67 -0
- package/admin/js/views/menu-editor.js +22 -20
- package/admin/js/views/settings.js +3 -3
- package/docs/DommaFeatures.md +11 -0
- package/docs/markdown-shortcodes.md +17 -2
- package/package.json +1 -1
- package/plugins/_lib/admin/mail/reader-view.js +36 -8
- package/plugins/_lib/admin/mail/rules.js +81 -0
- package/plugins/_lib/mail/accounts.js +27 -3
- package/plugins/_lib/mail/sync.js +4 -1
- package/public/css/footer-showcase.css +1 -0
- package/public/css/menu-cards.css +1 -0
- package/public/css/page-motion.css +1 -0
- package/public/js/footer-showcase.mjs +8 -0
- package/public/js/menu-cards.mjs +11 -0
- package/public/js/menu-look.mjs +1 -0
- package/public/js/page-motion.mjs +1 -0
- package/public/js/site.js +1 -1
- package/public/js/text-style.mjs +1 -1
- package/server/services/markdown.js +22 -11
- package/server/services/menus.js +15 -0
- package/server/services/renderer.js +4 -0
- package/server/templates/page.html +4 -1
|
@@ -19,7 +19,7 @@ import {contentsOverrideFromAttrs} from './pageContents.js';
|
|
|
19
19
|
import {buildMenuNav} from './menuRender.js';
|
|
20
20
|
import {checkVisibility} from '../middleware/auth.js';
|
|
21
21
|
import {getRoleHierarchy, getRoleLevel} from './roles.js';
|
|
22
|
-
import {buildTextStyle} from '../../public/js/text-style.mjs';
|
|
22
|
+
import {buildTextStyle, buildTextMotion} from '../../public/js/text-style.mjs';
|
|
23
23
|
import {buildScribeStyle} from '../../public/js/scribe-style.mjs';
|
|
24
24
|
import {CHARACTERS, resolveCharacterSize} from '../../public/js/celebrations/character-catalog.mjs';
|
|
25
25
|
import {publicButtonSettings} from '../../public/js/form-submit.mjs';
|
|
@@ -2348,7 +2348,10 @@ function processGridBlocks(markdown) {
|
|
|
2348
2348
|
const revealStagger = attrs['reveal-stagger'] ? ` data-reveal-stagger="${escapeAttr(attrs['reveal-stagger'])}"` : '';
|
|
2349
2349
|
const revealDelay = attrs['reveal-delay'] ? ` data-reveal-delay="${escapeAttr(attrs['reveal-delay'])}"` : '';
|
|
2350
2350
|
const revealDirection = attrs['reveal-direction'] ? ` data-reveal-direction="${escapeAttr(attrs['reveal-direction'])}"` : '';
|
|
2351
|
-
|
|
2351
|
+
// Swoosh in again each time the row comes back up into view; cards that lean toward the pointer.
|
|
2352
|
+
const revealReplay = isTruthyAttr(attrs['reveal-replay']) ? ' data-reveal-replay="true"' : '';
|
|
2353
|
+
const tilt = isTruthyAttr(attrs.tilt) ? ' data-tilt="true"' : '';
|
|
2354
|
+
return `<div class="${classes.join(' ')}"${id}${reveal}${revealMode}${revealAnimation}${revealDuration}${revealStagger}${revealDelay}${revealDirection}${revealReplay}${tilt}>${inner}</div>\n`;
|
|
2352
2355
|
}
|
|
2353
2356
|
);
|
|
2354
2357
|
|
|
@@ -3690,19 +3693,27 @@ function processTextBlocks(markdown) {
|
|
|
3690
3693
|
const attrs = parseShortcodeAttrs(attrStr || '');
|
|
3691
3694
|
// The attribute → CSS mapping is shared with the admin editor's live
|
|
3692
3695
|
// preview (public/js/text-style.mjs), so the two cannot disagree.
|
|
3693
|
-
|
|
3696
|
+
// Gradient, shine, light-up and word-by-word (text-motion.mjs moves them).
|
|
3697
|
+
const motion = buildTextMotion(attrs);
|
|
3698
|
+
const style = [buildTextStyle(attrs), motion.style].filter(Boolean).join(';');
|
|
3694
3699
|
const styleAttr = style ? ` style="${style}"` : '';
|
|
3695
|
-
const
|
|
3700
|
+
const classes = [...motion.classes, ...(attrs.class ? [attrs.class] : [])].join(' ');
|
|
3701
|
+
const classAttr = classes ? ` class="${escapeAttr(classes)}"` : '';
|
|
3696
3702
|
const idAttr = attrs.id ? ` id="${escapeAttr(attrs.id)}"` : '';
|
|
3697
3703
|
|
|
3698
3704
|
return `<span${styleAttr}${classAttr}${idAttr}>${inner.trim()}</span>`;
|
|
3699
3705
|
}
|
|
3700
3706
|
|
|
3701
|
-
// Note: [\s\S]*? allows multi-line body content (deliberate divergence from badge's [^\n]*?)
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3707
|
+
// Note: [\s\S]*? allows multi-line body content (deliberate divergence from badge's [^\n]*?).
|
|
3708
|
+
// Innermost first, round again until none is left, so a [text] can sit inside another -
|
|
3709
|
+
// a gradient phrase inside a headline that rises word by word.
|
|
3710
|
+
const INNERMOST = /\[text(\s[^\]]*)?\]((?:(?!\[text[\s\]])[\s\S])*?)\[\/text\]/gi;
|
|
3711
|
+
let result = scrubbed;
|
|
3712
|
+
for (let pass = 0; pass < 8; pass++) {
|
|
3713
|
+
const next = result.replace(INNERMOST, (_, attrStr, body) => buildText(attrStr, body));
|
|
3714
|
+
if (next === result) break;
|
|
3715
|
+
result = next;
|
|
3716
|
+
}
|
|
3706
3717
|
|
|
3707
3718
|
return restore(result);
|
|
3708
3719
|
}
|
|
@@ -3985,8 +3996,8 @@ function processSpacerBlocks(markdown) {
|
|
|
3985
3996
|
* Any Behaviour setting of the menu, as attributes (see NAVBAR_OVERRIDE_ATTRS in
|
|
3986
3997
|
* menus.js): position, orientation, side, align, variant, hover-open, hover,
|
|
3987
3998
|
* selected, accent, class, font, font-size, font-weight, letter-spacing,
|
|
3988
|
-
* icon-size, width, collapsible, collapsed, autohide, hide-on-scroll
|
|
3989
|
-
* float-* panel options. `true` / `false` switch a setting on or off; an empty
|
|
3999
|
+
* icon-size, width, collapsible, collapsed, autohide, hide-on-scroll, bar, dropdown,
|
|
4000
|
+
* tiles, morph and the float-* panel options. `true` / `false` switch a setting on or off; an empty
|
|
3990
4001
|
* value clears it. Leaves a hidden marker the renderer reads (the first tag on
|
|
3991
4002
|
* a page counts) - it draws nothing itself.
|
|
3992
4003
|
*
|
package/server/services/menus.js
CHANGED
|
@@ -22,6 +22,9 @@ import {
|
|
|
22
22
|
PRESET_COLOUR_VARS, PRESET_COLOUR_FALLBACKS, colourToCss, cssClassProblems
|
|
23
23
|
} from '../../public/js/menu-decor.mjs';
|
|
24
24
|
import {fileIn} from './safePath.js';
|
|
25
|
+
import {normaliseLook, lookProblems, itemLookProblems} from '../../public/js/menu-look.mjs';
|
|
26
|
+
|
|
27
|
+
export {normaliseLook};
|
|
25
28
|
|
|
26
29
|
/**
|
|
27
30
|
* Bust the response-cache tags that menu changes affect. Public pages are
|
|
@@ -312,6 +315,8 @@ export const NAVBAR_OVERRIDE_ATTRS = {
|
|
|
312
315
|
'width': ['dock', 'width', 'num'], 'collapsible': ['dock', 'collapsible', 'bool'],
|
|
313
316
|
'collapsed': ['dock', 'collapsed', 'bool'], 'autohide': ['dock', 'autohide', 'bool'],
|
|
314
317
|
'hide-on-scroll': ['dock', 'hideOnScroll', 'bool'],
|
|
318
|
+
'bar': ['look', 'bar'], 'dropdown': ['look', 'dropdown'], 'tiles': ['look', 'tiles'],
|
|
319
|
+
'morph': ['look', 'morph', 'bool'],
|
|
315
320
|
'float-anchor': ['float', 'anchor'], 'float-x': ['float', 'offsetX', 'num'], 'float-y': ['float', 'offsetY', 'num'],
|
|
316
321
|
'float-width': ['float', 'width', 'num'], 'float-radius': ['float', 'radius', 'num'],
|
|
317
322
|
'float-shadow': ['float', 'shadow'], 'float-accent': ['float', 'accent'], 'float-opacity': ['float', 'opacity', 'num'],
|
|
@@ -367,6 +372,10 @@ export function applyMenuOverride(menu, override) {
|
|
|
367
372
|
const dock = normaliseDock(next.dock);
|
|
368
373
|
if (dock) next.dock = dock; else delete next.dock;
|
|
369
374
|
}
|
|
375
|
+
if (next.look) {
|
|
376
|
+
const look = normaliseLook(next.look);
|
|
377
|
+
if (look) next.look = look; else delete next.look;
|
|
378
|
+
}
|
|
370
379
|
return next;
|
|
371
380
|
}
|
|
372
381
|
|
|
@@ -620,6 +629,7 @@ export async function createMenu(input) {
|
|
|
620
629
|
...(input.style != null && {style: input.style}),
|
|
621
630
|
...(normaliseDock(input.dock) && {dock: normaliseDock(input.dock)}),
|
|
622
631
|
...(normaliseMobile(input.mobile) && {mobile: normaliseMobile(input.mobile)}),
|
|
632
|
+
...(normaliseLook(input.look) && {look: normaliseLook(input.look)}),
|
|
623
633
|
...(binding != null && {binding}),
|
|
624
634
|
items: Array.isArray(input.items) ? input.items : [],
|
|
625
635
|
meta: {
|
|
@@ -669,6 +679,7 @@ export async function updateMenu(slug, input) {
|
|
|
669
679
|
...(input.style != null && {style: input.style}),
|
|
670
680
|
...(normaliseDock(input.dock) && {dock: normaliseDock(input.dock)}),
|
|
671
681
|
...(normaliseMobile(input.mobile) && {mobile: normaliseMobile(input.mobile)}),
|
|
682
|
+
...(normaliseLook(input.look) && {look: normaliseLook(input.look)}),
|
|
672
683
|
...(binding != null && {binding}),
|
|
673
684
|
items: Array.isArray(input.items) ? input.items : [],
|
|
674
685
|
meta: {
|
|
@@ -886,6 +897,8 @@ export function validateMenu(menu) {
|
|
|
886
897
|
}
|
|
887
898
|
}
|
|
888
899
|
}
|
|
900
|
+
// Bar shape and dropdown style - see public/js/menu-look.mjs.
|
|
901
|
+
errors.push(...lookProblems(menu.look));
|
|
889
902
|
if (menu.highlight != null) {
|
|
890
903
|
if (typeof menu.highlight !== 'object' || Array.isArray(menu.highlight)) {
|
|
891
904
|
errors.push('highlight must be an object');
|
|
@@ -996,6 +1009,8 @@ export function validateMenu(menu) {
|
|
|
996
1009
|
if (item.colour != null && !isValidColour(item.colour)) {
|
|
997
1010
|
errors.push(`Item ${path}: colour must be a preset key or #rrggbb`);
|
|
998
1011
|
}
|
|
1012
|
+
// Card dropdown fields (description, tile, chip, panel) - menu-look.mjs.
|
|
1013
|
+
for (const p of itemLookProblems(item, isValidColour)) errors.push(`Item ${path}: ${p}`);
|
|
999
1014
|
for (const p of cssClassProblems(item.class)) errors.push(`Item ${path}: class: ${p}`);
|
|
1000
1015
|
// Per-item highlight override. Same shape and same value sets as
|
|
1001
1016
|
// the menu-level `highlight` block validated above - an item that
|
|
@@ -390,6 +390,8 @@ export async function renderPage(page, opts = {}) {
|
|
|
390
390
|
// wires it; width and autohide also shape the body below, from the first paint.
|
|
391
391
|
...(navMenu.dock && {dock: navMenu.dock}),
|
|
392
392
|
...(navMenu.mobile && {mobile: navMenu.mobile}),
|
|
393
|
+
// Bar shape and card dropdowns - drawn by menu-cards.mjs in the browser.
|
|
394
|
+
...(navMenu.look && {look: navMenu.look}),
|
|
393
395
|
// Item highlighting: the navbar is built in the browser, so the
|
|
394
396
|
// config has to travel to site.js rather than being rendered here.
|
|
395
397
|
...(navMenu.highlight && {highlight: navMenu.highlight}),
|
|
@@ -1205,6 +1207,8 @@ export async function renderBlogPage(templatePath, data = {}, seoMeta = {}) {
|
|
|
1205
1207
|
// wires it; width and autohide also shape the body below, from the first paint.
|
|
1206
1208
|
...(navMenu.dock && {dock: navMenu.dock}),
|
|
1207
1209
|
...(navMenu.mobile && {mobile: navMenu.mobile}),
|
|
1210
|
+
// Bar shape and card dropdowns - drawn by menu-cards.mjs in the browser.
|
|
1211
|
+
...(navMenu.look && {look: navMenu.look}),
|
|
1208
1212
|
// Item highlighting: the navbar is built in the browser, so the
|
|
1209
1213
|
// config has to travel to site.js rather than being rendered here.
|
|
1210
1214
|
...(navMenu.highlight && {highlight: navMenu.highlight}),
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
<!-- Menu item hover / current-page effects. Loaded after site.css so a
|
|
31
31
|
menu's own highlight wins over the blanket link styling there. -->
|
|
32
32
|
<link rel="stylesheet" href="/public/css/menu-highlight.css?v=20261024-menu-highlight-fix">
|
|
33
|
+
<link rel="stylesheet" href="/public/css/menu-cards.css?v=20261029-menu-cards">
|
|
34
|
+
<link rel="stylesheet" href="/public/css/footer-showcase.css?v=20261029-footer-showcase">
|
|
35
|
+
<link rel="stylesheet" href="/public/css/page-motion.css?v=20261029-page-motion">
|
|
33
36
|
|
|
34
37
|
<!-- Font overrides -->
|
|
35
38
|
{{fontStyleTag}}
|
|
@@ -185,7 +188,7 @@
|
|
|
185
188
|
<script src="/public/js/form-logic-engine.js?v=20261025-dropzone-disable" defer></script>
|
|
186
189
|
|
|
187
190
|
<!-- Site initialisation -->
|
|
188
|
-
<script src="/public/js/site.js?v=
|
|
191
|
+
<script src="/public/js/site.js?v=20261029-page-motion" type="module"></script>
|
|
189
192
|
<script src="/public/js/collection-context.js?v=20261010-utf8-payloads" type="module"></script>
|
|
190
193
|
{{ctxMenusModule}}
|
|
191
194
|
|