domma-cms 0.17.0 → 0.18.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 (43) hide show
  1. package/CLAUDE.md +2 -0
  2. package/admin/css/dashboard.css +1 -1
  3. package/admin/index.html +2 -2
  4. package/admin/js/app.js +1 -1
  5. package/admin/js/lib/card-builder.js +3 -3
  6. package/admin/js/lib/effects-builder.js +1 -1
  7. package/admin/js/lib/markdown-toolbar.js +5 -5
  8. package/admin/js/templates/dashboard/cache.html +32 -0
  9. package/admin/js/templates/dashboard.html +4 -0
  10. package/admin/js/templates/settings.html +26 -0
  11. package/admin/js/views/block-editor-enhance.js +1 -1
  12. package/admin/js/views/dashboard/widgets/activity-feed.js +1 -1
  13. package/admin/js/views/dashboard/widgets/cache.js +1 -0
  14. package/admin/js/views/dashboard/widgets/journeys.js +1 -1
  15. package/admin/js/views/dashboard/widgets/spike-feed.js +1 -1
  16. package/admin/js/views/dashboard/widgets/top-pages.js +1 -1
  17. package/admin/js/views/dashboard.js +1 -1
  18. package/admin/js/views/form-editor.js +6 -6
  19. package/admin/js/views/index.js +1 -1
  20. package/admin/js/views/page-editor.js +42 -37
  21. package/admin/js/views/settings.js +3 -3
  22. package/config/cache.json +4 -0
  23. package/config/cache.json.example +12 -0
  24. package/package.json +1 -1
  25. package/public/js/forms.js +1 -1
  26. package/public/js/site.js +1 -1
  27. package/server/config.js +12 -1
  28. package/server/routes/api/cache.js +57 -0
  29. package/server/routes/api/navigation.js +2 -0
  30. package/server/routes/api/settings.js +3 -0
  31. package/server/routes/public.js +11 -3
  32. package/server/server.js +16 -3
  33. package/server/services/blocks.js +3 -0
  34. package/server/services/cache/drivers/MemoryDriver.js +118 -0
  35. package/server/services/cache/drivers/NoneDriver.js +12 -0
  36. package/server/services/cache/index.js +229 -0
  37. package/server/services/cache/lru.js +61 -0
  38. package/server/services/collections.js +17 -4
  39. package/server/services/content.js +7 -2
  40. package/server/services/forms.js +3 -0
  41. package/server/services/markdown.js +25 -15
  42. package/server/services/views.js +4 -0
  43. package/server/templates/page.html +130 -130
@@ -1,130 +1,130 @@
1
- <!DOCTYPE html>
2
- <html lang="en-GB">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>{{seoTitle}}</title>
7
- <meta name="description" content="{{seoDescription}}">
8
- {{#if ogImage}}<meta property="og:image" content="{{ogImage}}">{{/if}}
9
-
10
- <!-- Fonts -->
11
- {{#if fontLink}}{{fontLink}}{{/if}}
12
-
13
- <!-- DommaJS CSS -->
14
- <link rel="stylesheet" href="/dist/domma/domma.css">
15
- <link rel="stylesheet" href="/dist/domma/grid.css">
16
- <link rel="stylesheet" href="/dist/domma/elements.css">
17
- <link rel="stylesheet" href="/dist/domma/themes/domma-themes.css">
18
-
19
- <!-- Site CSS -->
20
- <link rel="stylesheet" href="/public/css/site.css">
21
- <link rel="stylesheet" href="/public/css/forms.css">
22
-
23
- <!-- Font overrides -->
24
- {{fontStyleTag}}
25
-
26
- <!-- Plugin head injection -->
27
- {{headInject}}
28
-
29
- <!-- Late head injection — custom CSS always loads last so it can override everything -->
30
- {{headInjectLate}}
31
- </head>
32
- <body class="dm-cloaked dm-theme-{{theme}} {{layoutBodyClass}}" data-layout="{{layout}}">
33
-
34
- {{#if showNavbar}}
35
- <nav id="site-navbar"></nav>
36
- {{/if}}
37
-
38
- <main class="site-main {{#if showSidebar}}with-sidebar{{/if}}">
39
- {{#if showSidebar}}
40
- <aside id="site-sidebar" class="site-sidebar"></aside>
41
- {{/if}}
42
-
43
- <article class="site-content">
44
- <div class="container">
45
- {{breadcrumbsHtml}}
46
- <div class="page-body"{{#if pageBodyStyle}} style="{{pageBodyStyle}}"{{/if}}>
47
- {{html}}
48
- </div>
49
- </div>
50
- </article>
51
- </main>
52
-
53
- {{#if showFooter}}
54
- <footer id="site-footer" class="page-footer"></footer>
55
- {{/if}}
56
-
57
- <!-- DOMPurify - must load before DommaJS -->
58
- <script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>
59
-
60
- <!-- DommaJS -->
61
- <script src="/dist/domma/domma.min.js"></script>
62
-
63
- <!-- Initialise DommaJS before module loads -->
64
- <script>
65
- (function () {
66
- var _stored;
67
- try {
68
- _stored = JSON.parse(localStorage.getItem('domma:reduced_motion'));
69
- } catch (e) {
70
- }
71
- if (_stored === true) {
72
- document.documentElement.classList.add('dm-reduced-motion');
73
- }
74
- // Override window.matchMedia so Domma JS effects (scribe, breathe, etc.)
75
- // respect the stored preference. When explicitly set to false the user is
76
- // overriding the OS "reduce" preference to allow motion on this site.
77
- if (_stored !== null && _stored !== undefined && window.matchMedia) {
78
- var _orig = window.matchMedia.bind(window);
79
- window.matchMedia = function (q) {
80
- if (q === '(prefers-reduced-motion: reduce)') {
81
- return {
82
- matches: !!_stored, media: q, onchange: null,
83
- addListener: function () {
84
- }, removeListener: function () {
85
- },
86
- addEventListener: function () {
87
- }, removeEventListener: function () {
88
- },
89
- dispatchEvent: function () {
90
- return false;
91
- }
92
- };
93
- }
94
- return _orig(q);
95
- };
96
- }
97
- }());
98
- if (window.Domma && typeof window.Domma.init === 'function') {
99
- window.Domma.init();
100
- }
101
- if (window.Domma && window.Domma.theme) {
102
- window.Domma.theme.init({ theme: '{{theme}}', persist: false });
103
- }
104
- window.__CMS_NAV__ = {{navJson}};
105
- window.__CMS_SITE__ = {{siteJson}};
106
- (function () {
107
- var c = window.__CMS_SITE__ && window.__CMS_SITE__.autoTheme;
108
- if (!c || !c.enabled) return;
109
- var n = new Date(), m = n.getHours() * 60 + n.getMinutes(), ds = (c.dayStart || "07:00").split(":"),
110
- ns = (c.nightStart || "19:00").split(":"), d = +ds[0] * 60 + (+ds[1] || 0),
111
- e = +ns[0] * 60 + (+ns[1] || 0), t = (m >= d && m < e) ? c.dayTheme : c.nightTheme;
112
- if (window.Domma && window.Domma.theme) window.Domma.theme.set(t);
113
- }());
114
- {{dconfigScript}}
115
- </script>
116
-
117
- <!-- Site initialisation -->
118
- <script src="/public/js/site.js" type="module"></script>
119
-
120
- <!-- Core Forms (logic engine must load before renderer) -->
121
- <script src="/public/js/form-logic-engine.js"></script>
122
- <script src="/public/js/forms.js" type="module"></script>
123
-
124
- <!-- Core effects runtime -->
125
- <script src="/public/js/effects.js"></script>
126
-
127
- <!-- Plugin body-end injection -->
128
- {{bodyEndInject}}
129
- </body>
130
- </html>
1
+ <!DOCTYPE html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{seoTitle}}</title>
7
+ <meta name="description" content="{{seoDescription}}">
8
+ {{#if ogImage}}<meta property="og:image" content="{{ogImage}}">{{/if}}
9
+
10
+ <!-- Fonts -->
11
+ {{#if fontLink}}{{fontLink}}{{/if}}
12
+
13
+ <!-- DommaJS CSS -->
14
+ <link rel="stylesheet" href="/dist/domma/domma.css">
15
+ <link rel="stylesheet" href="/dist/domma/grid.css">
16
+ <link rel="stylesheet" href="/dist/domma/elements.css">
17
+ <link rel="stylesheet" href="/dist/domma/themes/domma-themes.css">
18
+
19
+ <!-- Site CSS -->
20
+ <link rel="stylesheet" href="/public/css/site.css">
21
+ <link rel="stylesheet" href="/public/css/forms.css">
22
+
23
+ <!-- Font overrides -->
24
+ {{fontStyleTag}}
25
+
26
+ <!-- Plugin head injection -->
27
+ {{headInject}}
28
+
29
+ <!-- Late head injection — custom CSS always loads last so it can override everything -->
30
+ {{headInjectLate}}
31
+ </head>
32
+ <body class="dm-cloaked dm-theme-{{theme}} {{layoutBodyClass}}" data-layout="{{layout}}">
33
+
34
+ {{#if showNavbar}}
35
+ <nav id="site-navbar"></nav>
36
+ {{/if}}
37
+
38
+ <main class="site-main {{#if showSidebar}}with-sidebar{{/if}}">
39
+ {{#if showSidebar}}
40
+ <aside id="site-sidebar" class="site-sidebar"></aside>
41
+ {{/if}}
42
+
43
+ <article class="site-content">
44
+ <div class="container">
45
+ {{breadcrumbsHtml}}
46
+ <div class="page-body"{{#if pageBodyStyle}} style="{{pageBodyStyle}}"{{/if}}>
47
+ {{html}}
48
+ </div>
49
+ </div>
50
+ </article>
51
+ </main>
52
+
53
+ {{#if showFooter}}
54
+ <footer id="site-footer" class="page-footer"></footer>
55
+ {{/if}}
56
+
57
+ <!-- DOMPurify - must load before DommaJS -->
58
+ <script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>
59
+
60
+ <!-- DommaJS -->
61
+ <script src="/dist/domma/domma.min.js"></script>
62
+
63
+ <!-- Initialise DommaJS before module loads -->
64
+ <script>
65
+ (function () {
66
+ var _stored;
67
+ try {
68
+ _stored = JSON.parse(localStorage.getItem('domma:reduced_motion'));
69
+ } catch (e) {
70
+ }
71
+ if (_stored === true) {
72
+ document.documentElement.classList.add('dm-reduced-motion');
73
+ }
74
+ // Override window.matchMedia so Domma JS effects (scribe, breathe, etc.)
75
+ // respect the stored preference. When explicitly set to false the user is
76
+ // overriding the OS "reduce" preference to allow motion on this site.
77
+ if (_stored !== null && _stored !== undefined && window.matchMedia) {
78
+ var _orig = window.matchMedia.bind(window);
79
+ window.matchMedia = function (q) {
80
+ if (q === '(prefers-reduced-motion: reduce)') {
81
+ return {
82
+ matches: !!_stored, media: q, onchange: null,
83
+ addListener: function () {
84
+ }, removeListener: function () {
85
+ },
86
+ addEventListener: function () {
87
+ }, removeEventListener: function () {
88
+ },
89
+ dispatchEvent: function () {
90
+ return false;
91
+ }
92
+ };
93
+ }
94
+ return _orig(q);
95
+ };
96
+ }
97
+ }());
98
+ if (window.Domma && typeof window.Domma.init === 'function') {
99
+ window.Domma.init();
100
+ }
101
+ if (window.Domma && window.Domma.theme) {
102
+ window.Domma.theme.init({ theme: '{{theme}}', persist: false });
103
+ }
104
+ window.__CMS_NAV__ = {{navJson}};
105
+ window.__CMS_SITE__ = {{siteJson}};
106
+ (function () {
107
+ var c = window.__CMS_SITE__ && window.__CMS_SITE__.autoTheme;
108
+ if (!c || !c.enabled) return;
109
+ var n = new Date(), m = n.getHours() * 60 + n.getMinutes(), ds = (c.dayStart || "07:00").split(":"),
110
+ ns = (c.nightStart || "19:00").split(":"), d = +ds[0] * 60 + (+ds[1] || 0),
111
+ e = +ns[0] * 60 + (+ns[1] || 0), t = (m >= d && m < e) ? c.dayTheme : c.nightTheme;
112
+ if (window.Domma && window.Domma.theme) window.Domma.theme.set(t);
113
+ }());
114
+ {{dconfigScript}}
115
+ </script>
116
+
117
+ <!-- Site initialisation -->
118
+ <script src="/public/js/site.js?v=20260509-chooser" type="module"></script>
119
+
120
+ <!-- Core Forms (logic engine must load before renderer) -->
121
+ <script src="/public/js/form-logic-engine.js?v=20260509-chooser"></script>
122
+ <script src="/public/js/forms.js?v=20260509-chooser" type="module"></script>
123
+
124
+ <!-- Core effects runtime -->
125
+ <script src="/public/js/effects.js"></script>
126
+
127
+ <!-- Plugin body-end injection -->
128
+ {{bodyEndInject}}
129
+ </body>
130
+ </html>