domma-cms 1.6.32 → 1.6.33
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/admin/js/lib/effect-defs.js +1 -1
- package/admin/js/lib/effects-builder.js +2 -2
- package/admin/js/lib/favicon-generator.js +1 -0
- package/admin/js/lib/markdown-toolbar.js +9 -9
- package/admin/js/lib/page-comments.js +9 -0
- package/admin/js/lib/page-editor-reference.js +1 -1
- package/admin/js/lib/scribe-composer.js +1 -1
- package/admin/js/lib/scribe-model.js +1 -1
- package/admin/js/lib/shortcode-preview.js +1 -1
- package/admin/js/lib/site-settings-arrange.js +1 -1
- package/admin/js/lib/syntax-highlight.js +1 -1
- package/admin/js/templates/settings.html +25 -7
- package/admin/js/views/settings.js +4 -4
- package/package.json +1 -1
- package/public/js/effects.js +1 -1
- package/public/js/scribe-style.mjs +1 -0
- package/public/js/site.js +1 -1
- package/scripts/run-tests.mjs +4 -0
- package/server/routes/api/pages.js +3 -3
- package/server/routes/api/settings.js +20 -1
- package/server/routes/api/versions.js +4 -3
- package/server/services/favicon.js +33 -0
- package/server/services/markdown.js +17 -5
- package/server/services/versions.js +10 -0
- package/server/templates/page.html +3 -3
|
@@ -18,6 +18,7 @@ import {buildMenuNav} from './menuRender.js';
|
|
|
18
18
|
import {checkVisibility} from '../middleware/auth.js';
|
|
19
19
|
import {getRoleHierarchy, getRoleLevel} from './roles.js';
|
|
20
20
|
import {buildTextStyle} from '../../public/js/text-style.mjs';
|
|
21
|
+
import {buildScribeStyle} from '../../public/js/scribe-style.mjs';
|
|
21
22
|
import {CHARACTERS, resolveCharacterSize} from '../../public/js/celebrations/character-catalog.mjs';
|
|
22
23
|
import {publicButtonSettings} from '../../public/js/form-submit.mjs';
|
|
23
24
|
|
|
@@ -1680,7 +1681,7 @@ export function parseShortcodeAttrs(attrStr) {
|
|
|
1680
1681
|
*/
|
|
1681
1682
|
let scrubCallId = 0;
|
|
1682
1683
|
|
|
1683
|
-
export function scrubCodeRegions(markdown) {
|
|
1684
|
+
export function scrubCodeRegions(markdown, preserveIndented = false) {
|
|
1684
1685
|
const callId = ++scrubCallId;
|
|
1685
1686
|
const store = [];
|
|
1686
1687
|
const placeholder = (s) => {
|
|
@@ -1694,7 +1695,10 @@ export function scrubCodeRegions(markdown) {
|
|
|
1694
1695
|
// Collection bodies may already be HTML: inline examples remain literal too.
|
|
1695
1696
|
scrubbed = scrubbed.replace(/<code\b[^>]*>[\s\S]*?<\/code>/gi, placeholder);
|
|
1696
1697
|
// Fenced code blocks (``` or ~~~, with optional language tag)
|
|
1697
|
-
scrubbed =
|
|
1698
|
+
scrubbed = preserveIndented
|
|
1699
|
+
? scrubbed.replace(/^ {0,3}(`{3,}|~{3,})[^\n]*\n[\s\S]*?(?:\n {0,3}\1[ \t]*$|(?![\s\S]))/gm, placeholder)
|
|
1700
|
+
: scrubbed.replace(/^(`{3,}|~{3,})[^\n]*\n[\s\S]*?\n\1[ \t]*$/gm, placeholder);
|
|
1701
|
+
if (preserveIndented) scrubbed = scrubbed.replace(/^(?: {4}|\t)[^\r\n]*/gm, placeholder);
|
|
1698
1702
|
// Inline code spans (single or multiple backticks, non-greedy)
|
|
1699
1703
|
scrubbed = scrubbed.replace(/`+[^`\n]+`+/g, placeholder);
|
|
1700
1704
|
|
|
@@ -1847,12 +1851,14 @@ function processEffectsBlocks(markdown) {
|
|
|
1847
1851
|
if (typeof attrs[key] === 'string') attrs[key] = attrs[key].replace(/&(amp|quot|apos|lt|gt);/g, (_, name) => entities[name]);
|
|
1848
1852
|
}
|
|
1849
1853
|
const dataAttrs = Object.entries(attrs).map(([k, v]) => ` data-fx-${k}="${escapeAttr(v)}"`).join('');
|
|
1854
|
+
const scribeStyle = buildScribeStyle(attrs);
|
|
1855
|
+
const styleAttrs = scribeStyle ? ` style="${escapeAttr(scribeStyle)}"` : '';
|
|
1850
1856
|
const hasActions = /\[\s*(render|wait|undo|redraw)\b/i.test(body);
|
|
1851
1857
|
if (!hasActions) {
|
|
1852
1858
|
// Restore code placeholders before the nested parse (tabs-handler
|
|
1853
1859
|
// pattern) so code spans/fences render as <code>, not raw backticks.
|
|
1854
1860
|
const innerHtml = marked.parse(processCardBlocks(processGridBlocks(processInlineShortcodes(restore(body.trim())))));
|
|
1855
|
-
return `<div class="dm-fx-scribe"${dataAttrs}>${innerHtml}</div>\n`;
|
|
1861
|
+
return `<div class="dm-fx-scribe"${dataAttrs}${styleAttrs}>${innerHtml}</div>\n`;
|
|
1856
1862
|
}
|
|
1857
1863
|
const actions = [];
|
|
1858
1864
|
const actionRe = /\[render([^\]]*)\]([\s\S]*?)\[\/render\]|\[wait\]([\s\S]*?)\[\/wait\]|\[undo([^\]]*?)\/\]|\[redraw([^\]]*)\]([\s\S]*?)\[\/redraw\]/gi;
|
|
@@ -1881,7 +1887,7 @@ function processEffectsBlocks(markdown) {
|
|
|
1881
1887
|
}
|
|
1882
1888
|
}
|
|
1883
1889
|
if (!actions.length) return '';
|
|
1884
|
-
return `<span class="dm-fx-scribe"${dataAttrs} data-fx-actions="${escapeAttr(JSON.stringify(actions))}"></span>\n`;
|
|
1890
|
+
return `<span class="dm-fx-scribe"${dataAttrs}${styleAttrs} data-fx-actions="${escapeAttr(JSON.stringify(actions))}"></span>\n`;
|
|
1885
1891
|
});
|
|
1886
1892
|
|
|
1887
1893
|
for (const name of ['reveal', 'breathe', 'pulse', 'shake', 'scramble', 'ripple', 'twinkle']) {
|
|
@@ -4541,7 +4547,13 @@ export async function parseMarkdown(raw, opts = {}) {
|
|
|
4541
4547
|
// → listgroup → spacer → center → icon → demo → embed → form → hero → table
|
|
4542
4548
|
// → badge → text → button → link → cta → grid → card (+ box) → banner → slideover
|
|
4543
4549
|
// → marked → sanitize → afterParse
|
|
4544
|
-
|
|
4550
|
+
// Comments must be removed before shortcodes are expanded. Protect code
|
|
4551
|
+
// examples first; four-space-indented lines remain Markdown code too.
|
|
4552
|
+
const comments = scrubCodeRegions(content, true);
|
|
4553
|
+
const uncommented = comments.restore(comments.scrubbed
|
|
4554
|
+
.replace(/<!--[\s\S]*?(?:-->|$)/g, '')
|
|
4555
|
+
.replace(/^[ ]{0,3}\/\/[^\r\n]*/gm, ''));
|
|
4556
|
+
const preprocessed = applyTransforms('markdown:beforeParse', uncommented);
|
|
4545
4557
|
const {output: withComponents, used: usedComponents} = collectAndRewriteComponents(preprocessed);
|
|
4546
4558
|
const tagSet = new Set();
|
|
4547
4559
|
const flags = {perViewer: false};
|
|
@@ -7,6 +7,16 @@ import fs from 'fs/promises';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import {config} from '../config.js';
|
|
9
9
|
import {hooks} from './hooks.js';
|
|
10
|
+
import {getUserById} from './users.js';
|
|
11
|
+
|
|
12
|
+
/** Auth tokens carry name/email, rather than the old username field. */
|
|
13
|
+
export async function versionAuthor(user = {}) {
|
|
14
|
+
const record = user.id ? await getUserById(user.id) : null;
|
|
15
|
+
for (const value of [record?.name, user.name, user.username, record?.email, user.email, user.id]) {
|
|
16
|
+
if (typeof value === 'string' && value.trim()) return value.trim();
|
|
17
|
+
}
|
|
18
|
+
return 'Unknown user';
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
const VERSIONS_DIR = path.join(config.content.contentDir, 'versions');
|
|
12
22
|
const PAGES_DIR = path.join(config.content.contentDir, 'pages');
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>{{seoTitle}}</title>
|
|
7
7
|
<meta name="description" content="{{seoDescription}}">
|
|
8
|
-
<link rel="icon" href="/favicon.
|
|
8
|
+
<link rel="icon" href="/favicon.ico">
|
|
9
9
|
{{seoTags}}
|
|
10
10
|
|
|
11
11
|
<!-- Set on preview renders (editor preview, draft preview, share link).
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
</script>
|
|
174
174
|
|
|
175
175
|
<!-- Site initialisation -->
|
|
176
|
-
<script src="/public/js/site.js?v=20261012-
|
|
176
|
+
<script src="/public/js/site.js?v=20261012-timeline-icons" type="module"></script>
|
|
177
177
|
<script src="/public/js/collection-context.js?v=20261010-utf8-payloads" type="module"></script>
|
|
178
178
|
{{ctxMenusModule}}
|
|
179
179
|
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
<script src="/public/js/forms.js?v=20261009-form-classes" type="module"></script>
|
|
192
192
|
|
|
193
193
|
<!-- Core effects runtime -->
|
|
194
|
-
<script src="/public/js/effects.js?v=
|
|
194
|
+
<script src="/public/js/effects.js?v=20261012-scribe-typography"></script>
|
|
195
195
|
|
|
196
196
|
<!-- Plugin body-end injection -->
|
|
197
197
|
{{bodyEndInject}}
|