docula 1.9.1 → 1.10.1
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/dist/docula.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ type DoculaChangelogEntry = {
|
|
|
139
139
|
content: string;
|
|
140
140
|
generatedHtml: string;
|
|
141
141
|
preview: string;
|
|
142
|
+
draft?: boolean;
|
|
142
143
|
previewImage?: string;
|
|
143
144
|
urlPath: string;
|
|
144
145
|
lastModified: string;
|
|
@@ -180,6 +181,7 @@ type DoculaData = {
|
|
|
180
181
|
enableLlmsTxt?: boolean;
|
|
181
182
|
hasFeed?: boolean;
|
|
182
183
|
lastModified?: string;
|
|
184
|
+
homeUrl?: string;
|
|
183
185
|
baseUrl: string;
|
|
184
186
|
docsPath: string;
|
|
185
187
|
apiPath: string;
|
|
@@ -334,6 +336,11 @@ declare class DoculaOptions {
|
|
|
334
336
|
* When true, suppresses all non-error console output during the build.
|
|
335
337
|
*/
|
|
336
338
|
quiet: boolean;
|
|
339
|
+
/**
|
|
340
|
+
* URL for the logo/home link in the header. Defaults to baseUrl or "/".
|
|
341
|
+
* Useful when hosting docs under a subpath but the logo should link to the parent site.
|
|
342
|
+
*/
|
|
343
|
+
homeUrl?: string;
|
|
337
344
|
/**
|
|
338
345
|
* Base URL path prefix for all generated paths (e.g., "/docs").
|
|
339
346
|
* When set, all asset and navigation URLs are prefixed with this path.
|
package/dist/docula.js
CHANGED
|
@@ -1307,7 +1307,10 @@ import path5 from "path";
|
|
|
1307
1307
|
import { Writr as Writr4 } from "writr";
|
|
1308
1308
|
var writrOptions4 = {
|
|
1309
1309
|
throwOnEmitError: false,
|
|
1310
|
-
throwOnEmptyListeners: false
|
|
1310
|
+
throwOnEmptyListeners: false,
|
|
1311
|
+
renderOptions: {
|
|
1312
|
+
rawHtml: true
|
|
1313
|
+
}
|
|
1311
1314
|
};
|
|
1312
1315
|
function getChangelogEntries(changelogPath, options, hash, cachedEntries, previousHashes, currentHashes) {
|
|
1313
1316
|
const entries = [];
|
|
@@ -1330,6 +1333,9 @@ function getChangelogEntries(changelogPath, options, hash, cachedEntries, previo
|
|
|
1330
1333
|
}
|
|
1331
1334
|
}
|
|
1332
1335
|
const entry = parseChangelogEntry(filePath, options);
|
|
1336
|
+
if (entry.draft) {
|
|
1337
|
+
continue;
|
|
1338
|
+
}
|
|
1333
1339
|
entries.push(entry);
|
|
1334
1340
|
}
|
|
1335
1341
|
}
|
|
@@ -1375,6 +1381,7 @@ function parseChangelogEntry(filePath, options) {
|
|
|
1375
1381
|
});
|
|
1376
1382
|
}
|
|
1377
1383
|
const previewImage = matterData.previewImage;
|
|
1384
|
+
const draft = matterData.draft === true;
|
|
1378
1385
|
return {
|
|
1379
1386
|
title: matterData.title ?? fileName,
|
|
1380
1387
|
date: dateString,
|
|
@@ -1387,6 +1394,7 @@ function parseChangelogEntry(filePath, options) {
|
|
|
1387
1394
|
mdx: isMdx
|
|
1388
1395
|
}),
|
|
1389
1396
|
preview: generateChangelogPreview(markdownContent, 500, isMdx),
|
|
1397
|
+
draft,
|
|
1390
1398
|
previewImage,
|
|
1391
1399
|
urlPath: `${buildUrlPath(options.baseUrl, options.changelogPath, slug)}/index.html`,
|
|
1392
1400
|
lastModified: fs5.statSync(filePath).mtime.toISOString().split("T")[0]
|
|
@@ -1402,7 +1410,53 @@ function generateChangelogPreview(markdown, maxLength = 500, mdx = false) {
|
|
|
1402
1410
|
if (cleaned.length <= minLength) {
|
|
1403
1411
|
return new Writr4(cleaned, writrOptions4).renderSync({ mdx });
|
|
1404
1412
|
}
|
|
1405
|
-
const
|
|
1413
|
+
const htmlBlocks = [];
|
|
1414
|
+
const tagPattern = /<\/?(\w+)\b[^>]*>/g;
|
|
1415
|
+
const blockStarts = [];
|
|
1416
|
+
for (const tagMatch of cleaned.matchAll(tagPattern)) {
|
|
1417
|
+
const fullMatch = tagMatch[0];
|
|
1418
|
+
const tagName = tagMatch[1];
|
|
1419
|
+
const isClosing = fullMatch.startsWith("</");
|
|
1420
|
+
if (isClosing) {
|
|
1421
|
+
for (let i = blockStarts.length - 1; i >= 0; i--) {
|
|
1422
|
+
if (blockStarts[i].tag === tagName) {
|
|
1423
|
+
if (blockStarts[i].depth === 0) {
|
|
1424
|
+
htmlBlocks.push({
|
|
1425
|
+
start: blockStarts[i].index,
|
|
1426
|
+
end: tagMatch.index + fullMatch.length
|
|
1427
|
+
});
|
|
1428
|
+
blockStarts.splice(i, 1);
|
|
1429
|
+
} else {
|
|
1430
|
+
blockStarts[i].depth--;
|
|
1431
|
+
}
|
|
1432
|
+
break;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
} else if (!fullMatch.endsWith("/>")) {
|
|
1436
|
+
const existing = blockStarts.find((s) => s.tag === tagName);
|
|
1437
|
+
if (existing) {
|
|
1438
|
+
existing.depth++;
|
|
1439
|
+
} else {
|
|
1440
|
+
blockStarts.push({ tag: tagName, index: tagMatch.index, depth: 0 });
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
let effectiveMax = maxLength;
|
|
1445
|
+
let extended = true;
|
|
1446
|
+
while (extended) {
|
|
1447
|
+
extended = false;
|
|
1448
|
+
for (const block of htmlBlocks) {
|
|
1449
|
+
if (effectiveMax > block.start && effectiveMax < block.end) {
|
|
1450
|
+
let end = block.end;
|
|
1451
|
+
while (end < cleaned.length && cleaned[end] === "\n") {
|
|
1452
|
+
end++;
|
|
1453
|
+
}
|
|
1454
|
+
effectiveMax = end;
|
|
1455
|
+
extended = true;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
const searchArea = cleaned.slice(0, effectiveMax);
|
|
1406
1460
|
let splitIndex = -1;
|
|
1407
1461
|
let pos = searchArea.lastIndexOf("\n\n");
|
|
1408
1462
|
while (pos >= 0) {
|
|
@@ -1429,7 +1483,7 @@ function generateChangelogPreview(markdown, maxLength = 500, mdx = false) {
|
|
|
1429
1483
|
let lastItemEnd = -1;
|
|
1430
1484
|
for (const line of lines) {
|
|
1431
1485
|
const lineEnd = charCount + line.length;
|
|
1432
|
-
if (lineEnd <=
|
|
1486
|
+
if (lineEnd <= effectiveMax && (/^[-*]\s/.test(line) || /^\d+\.\s/.test(line))) {
|
|
1433
1487
|
if (charCount > 0 && charCount >= minLength) {
|
|
1434
1488
|
lastItemEnd = charCount - 1;
|
|
1435
1489
|
}
|
|
@@ -1445,7 +1499,7 @@ function generateChangelogPreview(markdown, maxLength = 500, mdx = false) {
|
|
|
1445
1499
|
const truncated2 = cleaned.slice(0, splitIndex).trim();
|
|
1446
1500
|
return new Writr4(truncated2, writrOptions4).renderSync({ mdx });
|
|
1447
1501
|
}
|
|
1448
|
-
let truncated = cleaned.slice(0,
|
|
1502
|
+
let truncated = cleaned.slice(0, effectiveMax);
|
|
1449
1503
|
const lastSpace = truncated.lastIndexOf(" ");
|
|
1450
1504
|
if (lastSpace > 0) {
|
|
1451
1505
|
truncated = truncated.slice(0, lastSpace);
|
|
@@ -2918,6 +2972,11 @@ var DoculaOptions = class {
|
|
|
2918
2972
|
* When true, suppresses all non-error console output during the build.
|
|
2919
2973
|
*/
|
|
2920
2974
|
quiet = false;
|
|
2975
|
+
/**
|
|
2976
|
+
* URL for the logo/home link in the header. Defaults to baseUrl or "/".
|
|
2977
|
+
* Useful when hosting docs under a subpath but the logo should link to the parent site.
|
|
2978
|
+
*/
|
|
2979
|
+
homeUrl;
|
|
2921
2980
|
/**
|
|
2922
2981
|
* Base URL path prefix for all generated paths (e.g., "/docs").
|
|
2923
2982
|
* When set, all asset and navigation URLs are prefixed with this path.
|
|
@@ -3074,6 +3133,9 @@ var DoculaOptions = class {
|
|
|
3074
3133
|
if (options.cache && typeof options.cache === "object" && options.cache.github !== null && typeof options.cache.github === "object" && typeof options.cache.github.ttl === "number") {
|
|
3075
3134
|
this.cache = options.cache;
|
|
3076
3135
|
}
|
|
3136
|
+
if (options.homeUrl !== void 0 && typeof options.homeUrl === "string") {
|
|
3137
|
+
this.homeUrl = options.homeUrl === "/" ? "/" : trimTrailingSlashes(options.homeUrl);
|
|
3138
|
+
}
|
|
3077
3139
|
if (options.baseUrl !== void 0 && typeof options.baseUrl === "string") {
|
|
3078
3140
|
this.baseUrl = trimTrailingSlashes(options.baseUrl);
|
|
3079
3141
|
}
|
|
@@ -3229,6 +3291,7 @@ var DoculaBuilder = class {
|
|
|
3229
3291
|
cookieAuth: this.options.cookieAuth,
|
|
3230
3292
|
headerLinks: this.options.headerLinks,
|
|
3231
3293
|
enableLlmsTxt: this.options.enableLlmsTxt,
|
|
3294
|
+
homeUrl: this.options.homeUrl,
|
|
3232
3295
|
baseUrl: this.options.baseUrl,
|
|
3233
3296
|
docsPath: this.options.docsPath,
|
|
3234
3297
|
apiPath: this.options.apiPath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docula",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.1",
|
|
4
4
|
"description": "Beautiful Website for Your Projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/docula.js",
|
|
@@ -48,14 +48,14 @@
|
|
|
48
48
|
"colorette": "^2.0.20",
|
|
49
49
|
"ecto": "^4.8.3",
|
|
50
50
|
"feed": "^5.2.0",
|
|
51
|
-
"hashery": "^1.5.
|
|
51
|
+
"hashery": "^1.5.1",
|
|
52
52
|
"jiti": "^2.6.1",
|
|
53
53
|
"serve-handler": "^6.1.7",
|
|
54
54
|
"update-notifier": "^7.3.1",
|
|
55
|
-
"writr": "^6.0
|
|
55
|
+
"writr": "^6.1.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@biomejs/biome": "^2.4.
|
|
58
|
+
"@biomejs/biome": "^2.4.8",
|
|
59
59
|
"@playwright/test": "^1.58.2",
|
|
60
60
|
"@types/express": "^5.0.6",
|
|
61
61
|
"@types/js-yaml": "^4.0.9",
|
|
@@ -68,10 +68,12 @@ body {
|
|
|
68
68
|
gap: 12px;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
.logo-link { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--fg); }
|
|
71
72
|
.logo__img {
|
|
72
73
|
height: 75px;
|
|
73
74
|
width: auto;
|
|
74
75
|
}
|
|
76
|
+
.logo__text { font-size: 18px; font-weight: 600; }
|
|
75
77
|
|
|
76
78
|
.theme-button {
|
|
77
79
|
border: 1px solid transparent;
|
|
@@ -354,8 +356,17 @@ body {
|
|
|
354
356
|
.article__main li, .release-body li, .changelog-entry-body li, .home-content li { margin-bottom: 6px; list-style: disc; }
|
|
355
357
|
.article__main ol li, .release-body ol li, .changelog-entry-body ol li, .home-content ol li { list-style: decimal; }
|
|
356
358
|
.article__main a, .release-body a, .changelog-entry-body a, .home-content a { color: var(--link); text-decoration: underline; }
|
|
357
|
-
.article__main pre, .release-body pre, .changelog-entry-body pre, .home-content pre { background: var(--pre-bg); border-radius: 6px; padding: 12px 16px; margin-bottom: 20px; overflow-x: auto; }
|
|
359
|
+
.article__main pre, .release-body pre, .changelog-entry-body pre, .home-content pre { background: var(--pre-bg); border-radius: 6px; padding: 12px 16px; margin-bottom: 20px; overflow-x: auto; position: relative; }
|
|
358
360
|
.article__main pre code, .release-body pre code, .changelog-entry-body pre code, .home-content pre code { background: none; padding: 0; font-size: 13.5px; line-height: 1.5; }
|
|
361
|
+
.copy-code-btn { position: absolute; top: 8px; right: 8px; padding: 4px; line-height: 0; border-radius: 4px; background: transparent; color: var(--muted); border: none; cursor: pointer; opacity: 0; transition: opacity 0.15s; }
|
|
362
|
+
pre:hover .copy-code-btn { opacity: 1; }
|
|
363
|
+
.copy-code-btn:hover { color: var(--fg); }
|
|
364
|
+
.article__main img, .changelog-entry-body img { cursor: zoom-in; }
|
|
365
|
+
.lightbox-overlay { display: none; position: fixed; inset: 0; z-index: 200; background: rgba(0, 0, 0, 0.8); justify-content: center; align-items: center; cursor: pointer; }
|
|
366
|
+
.lightbox-overlay--visible { display: flex !important; }
|
|
367
|
+
.lightbox-overlay img { max-width: 90vw; max-height: 90vh; border-radius: 8px; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4); cursor: default; }
|
|
368
|
+
.lightbox-close { position: absolute; top: 16px; right: 16px; background: none; border: none; color: #fff; cursor: pointer; padding: 4px; line-height: 0; }
|
|
369
|
+
.lightbox-close:hover { opacity: 0.7; }
|
|
359
370
|
.article__main blockquote, .release-body blockquote, .changelog-entry-body blockquote, .home-content blockquote { border-left: 3px solid var(--border-strong); padding: 10px 16px; margin-bottom: 15px; color: var(--muted); }
|
|
360
371
|
.article__main img, .release-body img, .changelog-entry-body img, .home-content img { max-width: 100%; border-radius: 6px; }
|
|
361
372
|
.article__main table, .release-body table, .changelog-entry-body table, .home-content table { width: 100%; border-collapse: collapse; margin-bottom: 15px; }
|
|
@@ -799,6 +810,11 @@ body {
|
|
|
799
810
|
color: var(--muted);
|
|
800
811
|
}
|
|
801
812
|
|
|
813
|
+
.changelog-entry-preview img {
|
|
814
|
+
max-width: 100%;
|
|
815
|
+
border-radius: 6px;
|
|
816
|
+
}
|
|
817
|
+
|
|
802
818
|
.changelog-read-more {
|
|
803
819
|
display: inline-block;
|
|
804
820
|
margin-top: 8px;
|
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="Toggle navigation menu">
|
|
5
5
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
|
6
6
|
</button>
|
|
7
|
-
<a href="{{baseUrl}}/">
|
|
7
|
+
<a href="{{baseUrl}}/" class="logo-link">
|
|
8
8
|
<img alt="{{siteTitle}}" class="logo__img" src="{{baseUrl}}/logo.svg">
|
|
9
|
+
<span class="logo__text">{{siteTitle}}</span>
|
|
9
10
|
</a>
|
|
10
11
|
<nav class="header-bottom__nav">
|
|
12
|
+
{{#if homeUrl}}
|
|
13
|
+
<a class="header-bottom__item header-bottom__item--home" href="{{homeUrl}}">
|
|
14
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>
|
|
15
|
+
<span>Back to Home</span>
|
|
16
|
+
</a>
|
|
17
|
+
{{/if}}
|
|
11
18
|
{{#if hasDocuments}}
|
|
12
19
|
<a class="header-bottom__item" href="{{docsUrl}}/" id="nav-docs">
|
|
13
20
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
@@ -67,6 +74,12 @@
|
|
|
67
74
|
</header>
|
|
68
75
|
<aside class="mobile-sidebar" id="mobile-sidebar">
|
|
69
76
|
<nav class="mobile-nav">
|
|
77
|
+
{{#if homeUrl}}
|
|
78
|
+
<a class="mobile-nav__item" href="{{homeUrl}}">
|
|
79
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>
|
|
80
|
+
<span>Back to Home</span>
|
|
81
|
+
</a>
|
|
82
|
+
{{/if}}
|
|
70
83
|
{{#if hasDocuments}}
|
|
71
84
|
<a class="mobile-nav__item" href="{{docsUrl}}/">
|
|
72
85
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
@@ -5,6 +5,25 @@
|
|
|
5
5
|
hljs.highlightAll();
|
|
6
6
|
var kbd = document.querySelector('.search-button__shortcut');
|
|
7
7
|
if (kbd) kbd.textContent = navigator.platform.indexOf('Mac') > -1 ? '⌘K' : 'Ctrl K';
|
|
8
|
+
|
|
9
|
+
// Copy code buttons
|
|
10
|
+
const copyIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>';
|
|
11
|
+
const checkIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>';
|
|
12
|
+
document.querySelectorAll('pre').forEach(function(pre) {
|
|
13
|
+
const btn = document.createElement('button');
|
|
14
|
+
btn.className = 'copy-code-btn';
|
|
15
|
+
btn.innerHTML = copyIcon;
|
|
16
|
+
btn.setAttribute('aria-label', 'Copy code');
|
|
17
|
+
btn.addEventListener('click', function() {
|
|
18
|
+
const code = pre.querySelector('code');
|
|
19
|
+
const text = code ? code.textContent : pre.textContent;
|
|
20
|
+
navigator.clipboard.writeText(text || '').then(function() {
|
|
21
|
+
btn.innerHTML = checkIcon;
|
|
22
|
+
setTimeout(function() { btn.innerHTML = copyIcon; }, 2000);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
pre.appendChild(btn);
|
|
26
|
+
});
|
|
8
27
|
});
|
|
9
28
|
</script>
|
|
10
29
|
<script>
|
|
@@ -115,6 +134,7 @@
|
|
|
115
134
|
function setAuthUI(loggedIn, displayName) {
|
|
116
135
|
window.__doculaAuth = { loggedIn: loggedIn, displayName: displayName };
|
|
117
136
|
try { localStorage.setItem('docula-auth-state', JSON.stringify(window.__doculaAuth)); } catch(e) {}
|
|
137
|
+
document.documentElement.classList.toggle('docula-auth-logged-in', loggedIn);
|
|
118
138
|
document.dispatchEvent(new CustomEvent('docula-auth-change'));
|
|
119
139
|
var els = [
|
|
120
140
|
{ login: document.getElementById('cookie-auth-login'), logout: document.getElementById('cookie-auth-logout'), user: document.getElementById('cookie-auth-user') },
|
|
@@ -243,5 +263,29 @@
|
|
|
243
263
|
const aside = tocSidebar.closest('.content-aside');
|
|
244
264
|
if (aside) { aside.style.display = 'none'; }
|
|
245
265
|
}
|
|
266
|
+
|
|
267
|
+
// Image lightbox
|
|
268
|
+
const lightboxOverlay = document.createElement('div');
|
|
269
|
+
lightboxOverlay.className = 'lightbox-overlay';
|
|
270
|
+
lightboxOverlay.addEventListener('click', function(e) {
|
|
271
|
+
if (e.target !== lightboxImg) lightboxOverlay.classList.remove('lightbox-overlay--visible');
|
|
272
|
+
});
|
|
273
|
+
const lightboxClose = document.createElement('button');
|
|
274
|
+
lightboxClose.className = 'lightbox-close';
|
|
275
|
+
lightboxClose.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
|
|
276
|
+
lightboxClose.addEventListener('click', function() {
|
|
277
|
+
lightboxOverlay.classList.remove('lightbox-overlay--visible');
|
|
278
|
+
});
|
|
279
|
+
const lightboxImg = document.createElement('img');
|
|
280
|
+
lightboxOverlay.appendChild(lightboxClose);
|
|
281
|
+
lightboxOverlay.appendChild(lightboxImg);
|
|
282
|
+
document.body.appendChild(lightboxOverlay);
|
|
283
|
+
|
|
284
|
+
document.querySelectorAll('.article__main img, .changelog-entry-body img').forEach(function(img) {
|
|
285
|
+
img.addEventListener('click', function() {
|
|
286
|
+
lightboxImg.src = img.src;
|
|
287
|
+
lightboxOverlay.classList.add('lightbox-overlay--visible');
|
|
288
|
+
});
|
|
289
|
+
});
|
|
246
290
|
});
|
|
247
291
|
</script>
|