@mgks/docmd 0.3.0 → 0.3.2
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/.github/ISSUE_TEMPLATE/bug_report.yml +4 -4
- package/.github/workflows/{publish.yml → npm-publish.yml} +2 -2
- package/package.json +1 -1
- package/src/assets/css/docmd-main.css +490 -471
- package/src/assets/js/docmd-main.js +36 -0
- package/src/assets/js/docmd-search.js +9 -3
- package/src/core/config-validator.js +2 -1
- package/src/templates/layout.ejs +20 -6
- package/src/templates/no-style.ejs +5 -1
- package/src/templates/partials/theme-init.js +20 -16
- package/src/templates/toc.ejs +1 -1
|
@@ -68,6 +68,41 @@ function initializeCollapsibleNav() {
|
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
// --- Mobile Menu Logic ---
|
|
72
|
+
function initializeMobileMenus() {
|
|
73
|
+
// 1. Sidebar Toggle
|
|
74
|
+
const sidebarBtn = document.querySelector('.sidebar-menu-button');
|
|
75
|
+
const sidebar = document.querySelector('.sidebar');
|
|
76
|
+
|
|
77
|
+
if (sidebarBtn && sidebar) {
|
|
78
|
+
sidebarBtn.addEventListener('click', (e) => {
|
|
79
|
+
e.stopPropagation(); // Prevent bubbling
|
|
80
|
+
sidebar.classList.toggle('mobile-expanded');
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 2. TOC Toggle
|
|
85
|
+
const tocBtn = document.querySelector('.toc-menu-button');
|
|
86
|
+
const tocContainer = document.querySelector('.toc-container');
|
|
87
|
+
// Also allow clicking the title text to toggle
|
|
88
|
+
const tocTitle = document.querySelector('.toc-title');
|
|
89
|
+
|
|
90
|
+
const toggleToc = (e) => {
|
|
91
|
+
// Only engage on mobile view (check if button is visible)
|
|
92
|
+
if (window.getComputedStyle(tocBtn).display === 'none') return;
|
|
93
|
+
|
|
94
|
+
e.stopPropagation();
|
|
95
|
+
tocContainer.classList.toggle('mobile-expanded');
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if (tocBtn && tocContainer) {
|
|
99
|
+
tocBtn.addEventListener('click', toggleToc);
|
|
100
|
+
if (tocTitle) {
|
|
101
|
+
tocTitle.addEventListener('click', toggleToc);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
71
106
|
// --- Sidebar Scroll Preservation ---
|
|
72
107
|
function initializeSidebarScroll() {
|
|
73
108
|
const sidebar = document.querySelector('.sidebar');
|
|
@@ -245,5 +280,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
245
280
|
initializeTabs();
|
|
246
281
|
initializeCopyCodeButtons();
|
|
247
282
|
initializeCollapsibleNav();
|
|
283
|
+
initializeMobileMenus();
|
|
248
284
|
initializeSidebarScroll();
|
|
249
285
|
});
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
const searchInput = document.getElementById('docmd-search-input');
|
|
14
14
|
const searchResults = document.getElementById('docmd-search-results');
|
|
15
15
|
|
|
16
|
+
const ROOT_PATH = window.DOCMD_ROOT || './';
|
|
17
|
+
|
|
16
18
|
if (!searchModal) return;
|
|
17
19
|
|
|
18
20
|
const emptyStateHtml = '<div class="search-initial">Type to start searching...</div>';
|
|
@@ -102,8 +104,9 @@
|
|
|
102
104
|
// 3. Index Loading Logic
|
|
103
105
|
async function loadIndex() {
|
|
104
106
|
try {
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
+
|
|
108
|
+
const indexUrl = `${ROOT_PATH}search-index.json`;
|
|
109
|
+
const response = await fetch(indexUrl);
|
|
107
110
|
if (!response.ok) throw new Error(response.status);
|
|
108
111
|
|
|
109
112
|
const jsonString = await response.text();
|
|
@@ -188,9 +191,12 @@
|
|
|
188
191
|
|
|
189
192
|
const html = results.slice(0, 10).map((result, index) => {
|
|
190
193
|
const snippet = getSnippet(result.text, query);
|
|
194
|
+
|
|
195
|
+
const linkHref = `${ROOT_PATH}${result.id}`;
|
|
196
|
+
|
|
191
197
|
// Add data-index for mouse interaction tracking if needed
|
|
192
198
|
return `
|
|
193
|
-
<a href="
|
|
199
|
+
<a href="${linkHref}" class="search-result-item" data-index="${index}" onclick="window.closeDocmdSearch()">
|
|
194
200
|
<div class="search-result-title">${result.title}</div>
|
|
195
201
|
<div class="search-result-preview">${snippet}</div>
|
|
196
202
|
</a>
|
|
@@ -6,7 +6,8 @@ const chalk = require('chalk');
|
|
|
6
6
|
const KNOWN_KEYS = [
|
|
7
7
|
'siteTitle', 'siteUrl', 'srcDir', 'outputDir', 'logo',
|
|
8
8
|
'sidebar', 'theme', 'customJs', 'autoTitleFromH1',
|
|
9
|
-
'copyCode', 'plugins', 'navigation', 'footer', 'sponsor', 'favicon'
|
|
9
|
+
'copyCode', 'plugins', 'navigation', 'footer', 'sponsor', 'favicon',
|
|
10
|
+
'search', 'minify', 'editLink', 'pageNavigation'
|
|
10
11
|
];
|
|
11
12
|
|
|
12
13
|
// Common typos mapping
|
package/src/templates/layout.ejs
CHANGED
|
@@ -13,14 +13,19 @@
|
|
|
13
13
|
|
|
14
14
|
<%- faviconLinkHtml || '' %> <%# Favicon %>
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
<!-- Define Default Mode (Variable for script) -->
|
|
17
|
+
<script>
|
|
18
|
+
window.DOCMD_DEFAULT_MODE = "<%= defaultMode %>";
|
|
19
|
+
</script>
|
|
19
20
|
|
|
21
|
+
<!-- Highlight.js Theme -->
|
|
20
22
|
<% if (config.theme?.codeHighlight !== false) { %>
|
|
21
23
|
<link rel="stylesheet" id="highlight-theme" href="<%= relativePathToRoot %>assets/css/docmd-highlight-<%= defaultMode === 'dark' ? 'dark' : 'light' %>.css" data-base-href="<%= relativePathToRoot %>assets/css/">
|
|
22
24
|
<% } %>
|
|
23
25
|
|
|
26
|
+
<!-- Main Theme -->
|
|
27
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-main.css">
|
|
28
|
+
|
|
24
29
|
<%- themeCssLinkHtml || '' %> <%# For theme.name specific CSS %>
|
|
25
30
|
|
|
26
31
|
<% (customCssFiles || []).forEach(cssFile => { %>
|
|
@@ -29,10 +34,13 @@
|
|
|
29
34
|
|
|
30
35
|
<%- pluginStylesHtml || '' %> <%# Plugin specific CSS %>
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
<!-- This checks storage and updates HTML attr + Highlight CSS before final paint -->
|
|
38
|
+
<%- themeInitScript %>
|
|
39
|
+
|
|
40
|
+
<%- pluginHeadScriptsHtml || '' %> <%# Plugin specific head scripts %>
|
|
33
41
|
</head>
|
|
34
42
|
<body class="<%= sidebarConfig.collapsible ? 'sidebar-collapsible' : 'sidebar-not-collapsible' %>"
|
|
35
|
-
data-
|
|
43
|
+
data-default-collapsed="<%= sidebarConfig.defaultCollapsed %>"
|
|
36
44
|
data-copy-code-enabled="<%= config.copyCode === true %>">
|
|
37
45
|
<aside class="sidebar">
|
|
38
46
|
<div class="sidebar-header">
|
|
@@ -44,11 +52,13 @@
|
|
|
44
52
|
<% } else { %>
|
|
45
53
|
<h1><a href="<%= relativePathToRoot %>index.html"><%= siteTitle %></a></h1>
|
|
46
54
|
<% } %>
|
|
55
|
+
<span class="mobile-view sidebar-menu-button float-right">
|
|
56
|
+
<%- renderIcon("ellipsis-vertical") %>
|
|
57
|
+
</span>
|
|
47
58
|
</div>
|
|
48
59
|
<%- navigationHtml %>
|
|
49
60
|
<% if (theme && theme.enableModeToggle && theme.positionMode !== 'top') { %>
|
|
50
61
|
<button id="theme-toggle-button" aria-label="Toggle theme" class="theme-toggle-button">
|
|
51
|
-
<%# renderIcon is available in the global EJS scope from html-generator %>
|
|
52
62
|
<%- renderIcon('sun', { class: 'icon-sun' }) %>
|
|
53
63
|
<%- renderIcon('moon', { class: 'icon-moon' }) %>
|
|
54
64
|
</button>
|
|
@@ -174,6 +184,10 @@
|
|
|
174
184
|
</div>
|
|
175
185
|
<% } %>
|
|
176
186
|
|
|
187
|
+
<script>
|
|
188
|
+
window.DOCMD_ROOT = "<%= relativePathToRoot %>";
|
|
189
|
+
</script>
|
|
190
|
+
|
|
177
191
|
<script src="<%= relativePathToRoot %>assets/js/docmd-main.js"></script>
|
|
178
192
|
|
|
179
193
|
<% if (config.search !== false) { %>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<% } %>
|
|
18
18
|
|
|
19
19
|
<% if (frontmatter.components?.themeMode !== false) { %>
|
|
20
|
-
|
|
20
|
+
<script>window.DOCMD_DEFAULT_MODE = "<%= defaultMode %>";</script>
|
|
21
21
|
<% } %>
|
|
22
22
|
|
|
23
23
|
<% if (frontmatter.components?.css !== false) { %>
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
<% } %>
|
|
28
28
|
<% } %>
|
|
29
29
|
|
|
30
|
+
<% if (frontmatter.components?.themeMode !== false) { %>
|
|
31
|
+
<%- themeInitScript %>
|
|
32
|
+
<% } %>
|
|
33
|
+
|
|
30
34
|
<% if (frontmatter.components?.theme !== false) { %>
|
|
31
35
|
<%- themeCssLinkHtml || '' %>
|
|
32
36
|
<% } %>
|
|
@@ -5,22 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
(function() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
try {
|
|
9
|
+
// Determine Theme
|
|
10
|
+
var localValue = localStorage.getItem('docmd-theme');
|
|
11
|
+
var configValue = window.DOCMD_DEFAULT_MODE || 'light';
|
|
12
|
+
var theme = localValue ? localValue : configValue;
|
|
13
|
+
|
|
14
|
+
// Set HTML Attribute (for main CSS variables)
|
|
15
|
+
document.documentElement.setAttribute('data-theme', theme);
|
|
16
|
+
|
|
17
|
+
// Handle Highlight.js Theme (if present)
|
|
18
|
+
var highlightLink = document.getElementById('highlight-theme');
|
|
19
|
+
if (highlightLink) {
|
|
20
|
+
var baseHref = highlightLink.getAttribute('data-base-href');
|
|
21
|
+
// Check if the current href matches the desired theme
|
|
22
|
+
// If not, swap it immediately before the browser renders code blocks
|
|
23
|
+
if (baseHref && !highlightLink.href.includes('docmd-highlight-' + theme)) {
|
|
24
|
+
highlightLink.href = baseHref + 'docmd-highlight-' + theme + '.css';
|
|
22
25
|
}
|
|
23
|
-
} catch (e) {
|
|
24
|
-
console.error('Error applying theme from localStorage', e);
|
|
25
26
|
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error('Theme init failed', e);
|
|
29
|
+
}
|
|
26
30
|
})();
|
package/src/templates/toc.ejs
CHANGED
|
@@ -54,7 +54,7 @@ if (shouldShowToc && !frontmatter?.toc || frontmatter?.toc !== 'false') {
|
|
|
54
54
|
if (tocHeadings.length > 1) {
|
|
55
55
|
%>
|
|
56
56
|
<div class="toc-container">
|
|
57
|
-
<h2 class="toc-title">On This Page
|
|
57
|
+
<h2 class="toc-title">On This Page<span class="mobile-view toc-menu-button float-right"><%- renderIcon("chevrons-down-up") %></span></h2>
|
|
58
58
|
<ul class="toc-list">
|
|
59
59
|
<% tocHeadings.forEach(heading => { %>
|
|
60
60
|
<li class="toc-item toc-level-<%= heading.level %>">
|