hexo-theme-redefine-x 2.8.5
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-chinese.yml +115 -0
- package/.github/ISSUE_TEMPLATE/bug-english.yml +106 -0
- package/.github/ISSUE_TEMPLATE/enhancement-chinese.yml +55 -0
- package/.github/ISSUE_TEMPLATE/enhancement-english.yml +55 -0
- package/.github/workflows/build-and-commit.yml +49 -0
- package/.github/workflows/npm-publish.yml +34 -0
- package/.github/workflows/stale-issues.yml +20 -0
- package/CHANGELOG_REDEFINE_X.md +236 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +51 -0
- package/DONATION.md +82 -0
- package/LICENSE +674 -0
- package/README.md +135 -0
- package/README_zh-CN.md +138 -0
- package/README_zh-TW.md +137 -0
- package/TODO.md +215 -0
- package/_config.yml +489 -0
- package/languages/en.yml +93 -0
- package/languages/es.yml +92 -0
- package/languages/fr.yml +92 -0
- package/languages/ja.yml +92 -0
- package/languages/zh-CN.yml +95 -0
- package/languages/zh-TW.yml +94 -0
- package/layout/404.ejs +1 -0
- package/layout/archive.ejs +1 -0
- package/layout/category.ejs +1 -0
- package/layout/components/comments/comment.ejs +22 -0
- package/layout/components/comments/giscus.ejs +42 -0
- package/layout/components/comments/gitalk.ejs +47 -0
- package/layout/components/comments/twikoo.ejs +50 -0
- package/layout/components/comments/waline.ejs +34 -0
- package/layout/components/footer/footer.ejs +99 -0
- package/layout/components/header/head.ejs +222 -0
- package/layout/components/header/navbar.ejs +163 -0
- package/layout/components/header/preloader.ejs +148 -0
- package/layout/components/header/progress-bar.ejs +12 -0
- package/layout/components/plugins/aplayer.ejs +3 -0
- package/layout/components/scripts.ejs +90 -0
- package/layout/components/sidebar/author.ejs +6 -0
- package/layout/components/sidebar/avatar.ejs +3 -0
- package/layout/components/sidebar/statistics.ejs +14 -0
- package/layout/components/swup.ejs +27 -0
- package/layout/index.ejs +1 -0
- package/layout/layout.ejs +13 -0
- package/layout/page.ejs +57 -0
- package/layout/pages/archive/archive.ejs +3 -0
- package/layout/pages/bookmarks/bookmarks.ejs +68 -0
- package/layout/pages/category/categories.ejs +11 -0
- package/layout/pages/category/category-detail.ejs +6 -0
- package/layout/pages/friends/friends-link.ejs +59 -0
- package/layout/pages/home/home-article.ejs +52 -0
- package/layout/pages/home/home-background.ejs +33 -0
- package/layout/pages/home/home-banner.ejs +234 -0
- package/layout/pages/home/home-content.ejs +62 -0
- package/layout/pages/home/home-sidebar.ejs +78 -0
- package/layout/pages/masonry/masonry.ejs +28 -0
- package/layout/pages/notfound/notfound.ejs +8 -0
- package/layout/pages/page-template.ejs +23 -0
- package/layout/pages/post/article-content.ejs +153 -0
- package/layout/pages/post/article-copyright.ejs +69 -0
- package/layout/pages/post/article-info.ejs +78 -0
- package/layout/pages/post/post-tools.ejs +17 -0
- package/layout/pages/post/toc.ejs +15 -0
- package/layout/pages/shuoshuo/essays.ejs +23 -0
- package/layout/pages/tag/tag-detail.ejs +6 -0
- package/layout/pages/tag/tags.ejs +24 -0
- package/layout/post.ejs +1 -0
- package/layout/tag.ejs +1 -0
- package/layout/tags.ejs +1 -0
- package/layout/utils/image-viewer.ejs +3 -0
- package/layout/utils/local-search.ejs +20 -0
- package/layout/utils/paginator.ejs +8 -0
- package/layout/utils/posts-list.ejs +28 -0
- package/layout/utils/side-tools.ejs +51 -0
- package/package.json +45 -0
- package/scripts/config-export.js +66 -0
- package/scripts/data-handle.js +37 -0
- package/scripts/events/404.js +16 -0
- package/scripts/events/welcome.js +141 -0
- package/scripts/filters/delete-mask-handle.js +27 -0
- package/scripts/filters/encrypt.js +202 -0
- package/scripts/filters/img-handle.js +9 -0
- package/scripts/filters/lazyload-handle.js +350 -0
- package/scripts/filters/lib/hbe.default.js +15 -0
- package/scripts/filters/link-handle.js +42 -0
- package/scripts/filters/stylus-handle.js +9 -0
- package/scripts/filters/table-handle.js +11 -0
- package/scripts/helpers/meta-helpers.js +38 -0
- package/scripts/helpers/page-helpers.js +153 -0
- package/scripts/helpers/recommendation-helpers.js +367 -0
- package/scripts/helpers/theme-helpers.js +251 -0
- package/scripts/helpers/waline-helpers.js +33 -0
- package/scripts/modules/btn.js +85 -0
- package/scripts/modules/btns.js +71 -0
- package/scripts/modules/folding.js +34 -0
- package/scripts/modules/note-large.js +72 -0
- package/scripts/modules/note.js +64 -0
- package/scripts/modules/tabs.js +99 -0
- package/source/assets/hbe.style.css +220 -0
- package/source/assets/odometer-theme-minimal.css +81 -0
- package/source/css/build/tailwind.css +2 -0
- package/source/css/common/animated.styl +71 -0
- package/source/css/common/basic.styl +239 -0
- package/source/css/common/codeblock/code-block.styl +158 -0
- package/source/css/common/codeblock/code-theme.styl +82 -0
- package/source/css/common/codeblock/highlight.styl +189 -0
- package/source/css/common/codeblock/hljs-themes/dark/a11y-dark.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/agate.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/atom-one-dark.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/github-dark.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/monokai-sublime.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/night-owl.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/nord.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/tokyo-night-dark.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/dark/vs2015.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/light/atom-one-light.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/light/default.styl +18 -0
- package/source/css/common/codeblock/hljs-themes/light/github.styl +18 -0
- package/source/css/common/colors.styl +112 -0
- package/source/css/common/markdown.styl +337 -0
- package/source/css/common/redefine-theme.styl +65 -0
- package/source/css/common/theme.styl +72 -0
- package/source/css/common/variables.styl +145 -0
- package/source/css/layout/_modules/aplayer.styl +799 -0
- package/source/css/layout/_modules/buttons.styl +42 -0
- package/source/css/layout/_modules/folding.styl +180 -0
- package/source/css/layout/_modules/notes.styl +181 -0
- package/source/css/layout/_modules/tabs.styl +105 -0
- package/source/css/layout/_partials/404.styl +14 -0
- package/source/css/layout/_partials/archive-list.styl +49 -0
- package/source/css/layout/_partials/article-copyright-info.styl +27 -0
- package/source/css/layout/_partials/article-meta-info.styl +62 -0
- package/source/css/layout/_partials/comments/comment.styl +11 -0
- package/source/css/layout/_partials/comments/gitalk.styl +529 -0
- package/source/css/layout/_partials/comments/twikoo.styl +62 -0
- package/source/css/layout/_partials/comments/waline.styl +1151 -0
- package/source/css/layout/_partials/footer.styl +59 -0
- package/source/css/layout/_partials/home-banner.styl +48 -0
- package/source/css/layout/_partials/image-viewer.styl +37 -0
- package/source/css/layout/_partials/local-search.styl +137 -0
- package/source/css/layout/_partials/navbar.styl +309 -0
- package/source/css/layout/_partials/page-template.styl +147 -0
- package/source/css/layout/_partials/paginator.styl +65 -0
- package/source/css/layout/_partials/post-tools.styl +43 -0
- package/source/css/layout/_partials/progress-bar.styl +33 -0
- package/source/css/layout/_partials/side-tools.styl +87 -0
- package/source/css/layout/_partials/tagcloud.styl +136 -0
- package/source/css/layout/_partials/toc.styl +105 -0
- package/source/css/layout/animations.styl +42 -0
- package/source/css/layout/archive-content.styl +8 -0
- package/source/css/layout/article-content.styl +257 -0
- package/source/css/layout/bookmarks.styl +8 -0
- package/source/css/layout/category-content.styl +21 -0
- package/source/css/layout/category-list.styl +119 -0
- package/source/css/layout/home-content.styl +114 -0
- package/source/css/layout/home-sidebar.styl +126 -0
- package/source/css/layout/page.styl +144 -0
- package/source/css/layout/tag-content.styl +30 -0
- package/source/css/style.styl +26 -0
- package/source/css/tailwind.source.css +236 -0
- package/source/fontawesome/all.min.css +6 -0
- package/source/fontawesome/brands.min.css +6 -0
- package/source/fontawesome/duotone.min.css +6 -0
- package/source/fontawesome/fontawesome.min.css +6 -0
- package/source/fontawesome/light.min.css +6 -0
- package/source/fontawesome/regular.min.css +6 -0
- package/source/fontawesome/sharp-solid.min.css +6 -0
- package/source/fontawesome/solid.min.css +6 -0
- package/source/fontawesome/svg-with-js.min.css +6 -0
- package/source/fontawesome/thin.min.css +6 -0
- package/source/fontawesome/v4-font-face.min.css +6 -0
- package/source/fontawesome/v4-shims.min.css +6 -0
- package/source/fontawesome/v5-font-face.min.css +6 -0
- package/source/fonts/Chillax/Chillax-Variable.eot +0 -0
- package/source/fonts/Chillax/Chillax-Variable.ttf +0 -0
- package/source/fonts/Chillax/Chillax-Variable.woff +0 -0
- package/source/fonts/Chillax/Chillax-Variable.woff2 +0 -0
- package/source/fonts/Chillax/chillax.css +39 -0
- package/source/fonts/Geist/GeistVF.ttf +0 -0
- package/source/fonts/Geist/GeistVF.woff +0 -0
- package/source/fonts/Geist/GeistVF.woff2 +0 -0
- package/source/fonts/Geist/geist.css +16 -0
- package/source/fonts/GeistMono/GeistMonoVF.ttf +0 -0
- package/source/fonts/GeistMono/GeistMonoVF.woff +0 -0
- package/source/fonts/GeistMono/GeistMonoVF.woff2 +0 -0
- package/source/fonts/GeistMono/geist-mono.css +16 -0
- package/source/images/bookmark-placeholder.svg +9 -0
- package/source/images/loading.svg +5 -0
- package/source/images/redefine-avatar.svg +1 -0
- package/source/images/redefine-favicon.svg +1 -0
- package/source/images/redefine-logo.svg +1 -0
- package/source/images/redefine-logo.webp +0 -0
- package/source/images/redefine-og.webp +0 -0
- package/source/images/wallhaven-wqery6-dark.webp +0 -0
- package/source/images/wallhaven-wqery6-light.webp +0 -0
- package/source/js/build/layouts/bookmarkNav.js +2 -0
- package/source/js/build/layouts/bookmarkNav.js.map +1 -0
- package/source/js/build/layouts/categoryList.js +2 -0
- package/source/js/build/layouts/categoryList.js.map +1 -0
- package/source/js/build/layouts/essays.js +2 -0
- package/source/js/build/layouts/essays.js.map +1 -0
- package/source/js/build/layouts/lazyload.js +2 -0
- package/source/js/build/layouts/lazyload.js.map +1 -0
- package/source/js/build/layouts/navbarShrink.js +2 -0
- package/source/js/build/layouts/navbarShrink.js.map +1 -0
- package/source/js/build/layouts/toc.js +2 -0
- package/source/js/build/layouts/toc.js.map +1 -0
- package/source/js/build/libs/APlayer.min.js +2 -0
- package/source/js/build/libs/Swup.min.js +2 -0
- package/source/js/build/libs/SwupPreloadPlugin.min.js +1 -0
- package/source/js/build/libs/SwupProgressPlugin.min.js +1 -0
- package/source/js/build/libs/SwupScriptsPlugin.min.js +1 -0
- package/source/js/build/libs/SwupScrollPlugin.min.js +1 -0
- package/source/js/build/libs/SwupSlideTheme.min.js +1 -0
- package/source/js/build/libs/Typed.min.js +10 -0
- package/source/js/build/libs/anime.min.js +8 -0
- package/source/js/build/libs/mermaid.min.js +2314 -0
- package/source/js/build/libs/minimasonry.min.js +1 -0
- package/source/js/build/libs/moment-with-locales.min.js +2 -0
- package/source/js/build/libs/moment.min.js +2 -0
- package/source/js/build/libs/odometer.min.js +2 -0
- package/source/js/build/libs/pangu.min.js +9 -0
- package/source/js/build/libs/pjax.min.js +1 -0
- package/source/js/build/libs/waline.js +84 -0
- package/source/js/build/main.js +2 -0
- package/source/js/build/main.js.map +1 -0
- package/source/js/build/plugins/aplayer.js +2 -0
- package/source/js/build/plugins/aplayer.js.map +1 -0
- package/source/js/build/plugins/hbe.js +2 -0
- package/source/js/build/plugins/hbe.js.map +1 -0
- package/source/js/build/plugins/masonry.js +2 -0
- package/source/js/build/plugins/masonry.js.map +1 -0
- package/source/js/build/plugins/mermaid.js +2 -0
- package/source/js/build/plugins/mermaid.js.map +1 -0
- package/source/js/build/plugins/pangu.js +2 -0
- package/source/js/build/plugins/pangu.js.map +1 -0
- package/source/js/build/plugins/tabs.js +2 -0
- package/source/js/build/plugins/tabs.js.map +1 -0
- package/source/js/build/plugins/typed.js +2 -0
- package/source/js/build/plugins/typed.js.map +1 -0
- package/source/js/build/tools/codeBlock.js +2 -0
- package/source/js/build/tools/codeBlock.js.map +1 -0
- package/source/js/build/tools/imageViewer.js +2 -0
- package/source/js/build/tools/imageViewer.js.map +1 -0
- package/source/js/build/tools/lightDarkSwitch.js +2 -0
- package/source/js/build/tools/lightDarkSwitch.js.map +1 -0
- package/source/js/build/tools/localSearch.js +2 -0
- package/source/js/build/tools/localSearch.js.map +1 -0
- package/source/js/build/tools/runtime.js +2 -0
- package/source/js/build/tools/runtime.js.map +1 -0
- package/source/js/build/tools/scrollTopBottom.js +2 -0
- package/source/js/build/tools/scrollTopBottom.js.map +1 -0
- package/source/js/build/tools/tocToggle.js +2 -0
- package/source/js/build/tools/tocToggle.js.map +1 -0
- package/source/js/build/utils.js +2 -0
- package/source/js/build/utils.js.map +1 -0
- package/source/js/build.js +148 -0
- package/source/js/layouts/bookmarkNav.js +65 -0
- package/source/js/layouts/categoryList.js +53 -0
- package/source/js/layouts/essays.js +25 -0
- package/source/js/layouts/lazyload.js +199 -0
- package/source/js/layouts/navbarShrink.js +135 -0
- package/source/js/layouts/toc.js +115 -0
- package/source/js/libs/APlayer.min.js +2 -0
- package/source/js/libs/APlayer.min.js.map +1 -0
- package/source/js/libs/Swup.min.js +2 -0
- package/source/js/libs/Swup.min.js.map +1 -0
- package/source/js/libs/SwupPreloadPlugin.min.js +1 -0
- package/source/js/libs/SwupPreloadPlugin.min.js.map +1 -0
- package/source/js/libs/SwupProgressPlugin.min.js +1 -0
- package/source/js/libs/SwupScriptsPlugin.min.js +1 -0
- package/source/js/libs/SwupScrollPlugin.min.js +1 -0
- package/source/js/libs/SwupScrollPlugin.min.js.map +1 -0
- package/source/js/libs/SwupSlideTheme.min.js +1 -0
- package/source/js/libs/Typed.min.js +10 -0
- package/source/js/libs/anime.min.js +8 -0
- package/source/js/libs/mermaid.min.js +2314 -0
- package/source/js/libs/mermaid.min.js.map +7 -0
- package/source/js/libs/minimasonry.min.js +1 -0
- package/source/js/libs/moment-with-locales.min.js +2 -0
- package/source/js/libs/moment.min.js +2 -0
- package/source/js/libs/odometer.min.js +2 -0
- package/source/js/libs/pangu.min.js +9 -0
- package/source/js/libs/pjax.min.js +1 -0
- package/source/js/libs/waline.js +84 -0
- package/source/js/libs/waline.js.map +1 -0
- package/source/js/main.js +95 -0
- package/source/js/plugins/aplayer.js +33 -0
- package/source/js/plugins/hbe.js +350 -0
- package/source/js/plugins/masonry.js +115 -0
- package/source/js/plugins/mermaid.js +7 -0
- package/source/js/plugins/pangu.js +12 -0
- package/source/js/plugins/tabs.js +29 -0
- package/source/js/plugins/typed.js +62 -0
- package/source/js/tools/codeBlock.js +48 -0
- package/source/js/tools/imageViewer.js +194 -0
- package/source/js/tools/lightDarkSwitch.js +165 -0
- package/source/js/tools/localSearch.js +327 -0
- package/source/js/tools/runtime.js +28 -0
- package/source/js/tools/scrollTopBottom.js +34 -0
- package/source/js/tools/tocToggle.js +58 -0
- package/source/js/utils.js +383 -0
- package/source/webfonts/fa-brands-400.ttf +0 -0
- package/source/webfonts/fa-brands-400.woff2 +0 -0
- package/source/webfonts/fa-duotone-900.ttf +0 -0
- package/source/webfonts/fa-duotone-900.woff2 +0 -0
- package/source/webfonts/fa-light-300.ttf +0 -0
- package/source/webfonts/fa-light-300.woff2 +0 -0
- package/source/webfonts/fa-regular-400.ttf +0 -0
- package/source/webfonts/fa-regular-400.woff2 +0 -0
- package/source/webfonts/fa-sharp-solid-900.ttf +0 -0
- package/source/webfonts/fa-sharp-solid-900.woff2 +0 -0
- package/source/webfonts/fa-solid-900.ttf +0 -0
- package/source/webfonts/fa-solid-900.woff2 +0 -0
- package/source/webfonts/fa-thin-100.ttf +0 -0
- package/source/webfonts/fa-thin-100.woff2 +0 -0
- package/source/webfonts/fa-v4compatibility.ttf +0 -0
- package/source/webfonts/fa-v4compatibility.woff2 +0 -0
- package/vercel.json +7 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Redefine-X Image Preloader - Build Phase
|
|
5
|
+
*
|
|
6
|
+
* This filter transforms <img> tags into <div class="img-preloader"> containers
|
|
7
|
+
* that will be processed by JavaScript at runtime for progressive loading.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const imageSize = require("image-size");
|
|
13
|
+
const http = require("http");
|
|
14
|
+
const https = require("https");
|
|
15
|
+
|
|
16
|
+
const DEFAULT_FALLBACK_DIMENSIONS = { width: 1000, height: 500 };
|
|
17
|
+
const REMOTE_MAX_BYTES = 12 * 1024 * 1024; // 12MB safety cap
|
|
18
|
+
const REMOTE_TIMEOUT_MS = 8000;
|
|
19
|
+
const REMOTE_MAX_REDIRECTS = 3;
|
|
20
|
+
|
|
21
|
+
const remoteSizeCache = new Map();
|
|
22
|
+
|
|
23
|
+
function escapeHtmlAttr(value) {
|
|
24
|
+
return String(value)
|
|
25
|
+
.replace(/&/g, "&")
|
|
26
|
+
.replace(/\"/g, """)
|
|
27
|
+
.replace(/</g, "<")
|
|
28
|
+
.replace(/>/g, ">");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function stripQueryAndHash(url) {
|
|
32
|
+
return String(url).split("#")[0].split("?")[0];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeRemoteUrl(src) {
|
|
36
|
+
const s = String(src).trim();
|
|
37
|
+
if (s.startsWith("//")) return `https:${s}`;
|
|
38
|
+
return s;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function decodeDataUrlToBuffer(src) {
|
|
42
|
+
const s = String(src);
|
|
43
|
+
if (!s.startsWith("data:")) return null;
|
|
44
|
+
const commaIndex = s.indexOf(",");
|
|
45
|
+
if (commaIndex === -1) return null;
|
|
46
|
+
const meta = s.slice(5, commaIndex);
|
|
47
|
+
const data = s.slice(commaIndex + 1);
|
|
48
|
+
const isBase64 = /;base64/i.test(meta);
|
|
49
|
+
try {
|
|
50
|
+
return isBase64
|
|
51
|
+
? Buffer.from(data, "base64")
|
|
52
|
+
: Buffer.from(decodeURIComponent(data), "utf8");
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function fetchUrlBuffer(urlString, redirectsLeft = REMOTE_MAX_REDIRECTS) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
let parsed;
|
|
61
|
+
try {
|
|
62
|
+
parsed = new URL(urlString);
|
|
63
|
+
} catch (e) {
|
|
64
|
+
reject(e);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const client = parsed.protocol === "http:" ? http : https;
|
|
69
|
+
const req = client.request(
|
|
70
|
+
parsed,
|
|
71
|
+
{
|
|
72
|
+
method: "GET",
|
|
73
|
+
headers: {
|
|
74
|
+
"User-Agent": "hexo-redefine-x-lazyload/1.0",
|
|
75
|
+
Accept: "image/*,*/*;q=0.8",
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
(res) => {
|
|
79
|
+
const status = res.statusCode || 0;
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
[301, 302, 303, 307, 308].includes(status) &&
|
|
83
|
+
res.headers.location &&
|
|
84
|
+
redirectsLeft > 0
|
|
85
|
+
) {
|
|
86
|
+
res.resume();
|
|
87
|
+
const nextUrl = new URL(res.headers.location, parsed).toString();
|
|
88
|
+
fetchUrlBuffer(nextUrl, redirectsLeft - 1).then(resolve, reject);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (status < 200 || status >= 300) {
|
|
93
|
+
res.resume();
|
|
94
|
+
reject(new Error(`HTTP ${status}`));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const chunks = [];
|
|
99
|
+
let total = 0;
|
|
100
|
+
res.on("data", (chunk) => {
|
|
101
|
+
total += chunk.length;
|
|
102
|
+
if (total > REMOTE_MAX_BYTES) {
|
|
103
|
+
req.destroy(new Error("Remote image too large"));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
chunks.push(chunk);
|
|
107
|
+
});
|
|
108
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
109
|
+
res.on("error", reject);
|
|
110
|
+
},
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
req.setTimeout(REMOTE_TIMEOUT_MS, () => {
|
|
114
|
+
req.destroy(new Error("Remote image request timeout"));
|
|
115
|
+
});
|
|
116
|
+
req.on("error", reject);
|
|
117
|
+
req.end();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function getImageDimensions(src, imgTag, data) {
|
|
122
|
+
const fromTag = tryGetDimensionsFromTag(imgTag);
|
|
123
|
+
if (fromTag) return fromTag;
|
|
124
|
+
|
|
125
|
+
const s = String(src).trim();
|
|
126
|
+
|
|
127
|
+
if (s.startsWith("data:")) {
|
|
128
|
+
const buffer = decodeDataUrlToBuffer(s);
|
|
129
|
+
if (buffer) {
|
|
130
|
+
try {
|
|
131
|
+
const size = imageSize(buffer);
|
|
132
|
+
if (size && size.width && size.height) return { width: size.width, height: size.height };
|
|
133
|
+
} catch {
|
|
134
|
+
// ignore
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (s.startsWith("blob:")) return null;
|
|
141
|
+
|
|
142
|
+
if (/^https?:\/\//i.test(s) || s.startsWith("//")) {
|
|
143
|
+
const normalized = normalizeRemoteUrl(s);
|
|
144
|
+
if (!remoteSizeCache.has(normalized)) {
|
|
145
|
+
remoteSizeCache.set(
|
|
146
|
+
normalized,
|
|
147
|
+
(async () => {
|
|
148
|
+
const buffer = await fetchUrlBuffer(normalized);
|
|
149
|
+
const size = imageSize(buffer);
|
|
150
|
+
if (size && size.width && size.height) return { width: size.width, height: size.height };
|
|
151
|
+
return null;
|
|
152
|
+
})(),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
return await remoteSizeCache.get(normalized);
|
|
158
|
+
} catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const localPath = resolveLocalImagePath(s, data);
|
|
164
|
+
if (localPath) {
|
|
165
|
+
try {
|
|
166
|
+
const size = imageSize(localPath);
|
|
167
|
+
if (size && size.width && size.height) return { width: size.width, height: size.height };
|
|
168
|
+
} catch {
|
|
169
|
+
// ignore
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function resolveLocalImagePath(src, data) {
|
|
177
|
+
const rawSrc = stripQueryAndHash(src);
|
|
178
|
+
|
|
179
|
+
const siteRoot = hexo.config.root || "/";
|
|
180
|
+
let rel = rawSrc;
|
|
181
|
+
if (siteRoot !== "/" && rel.startsWith(siteRoot)) {
|
|
182
|
+
rel = rel.slice(siteRoot.length);
|
|
183
|
+
}
|
|
184
|
+
rel = rel.replace(/^\//, "");
|
|
185
|
+
|
|
186
|
+
const relDecoded = (() => {
|
|
187
|
+
try {
|
|
188
|
+
return decodeURIComponent(rel);
|
|
189
|
+
} catch {
|
|
190
|
+
return rel;
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
|
|
194
|
+
const candidates = [];
|
|
195
|
+
|
|
196
|
+
if (hexo.source_dir) {
|
|
197
|
+
candidates.push(path.join(hexo.source_dir, relDecoded));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (hexo.theme_dir) {
|
|
201
|
+
candidates.push(path.join(hexo.theme_dir, "source", relDecoded));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const sourcePath = data && (data.full_source || data.source);
|
|
205
|
+
if (sourcePath) {
|
|
206
|
+
const sourceFullPath = path.isAbsolute(sourcePath)
|
|
207
|
+
? sourcePath
|
|
208
|
+
: path.join(hexo.source_dir || "", sourcePath);
|
|
209
|
+
candidates.push(path.join(path.dirname(sourceFullPath), relDecoded));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (hexo.source_dir && !rawSrc.startsWith("/")) {
|
|
213
|
+
const rawDecoded = (() => {
|
|
214
|
+
try {
|
|
215
|
+
return decodeURIComponent(rawSrc);
|
|
216
|
+
} catch {
|
|
217
|
+
return rawSrc;
|
|
218
|
+
}
|
|
219
|
+
})();
|
|
220
|
+
candidates.push(path.join(hexo.source_dir, rawDecoded));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
for (const candidate of candidates) {
|
|
224
|
+
try {
|
|
225
|
+
if (candidate && fs.existsSync(candidate)) return candidate;
|
|
226
|
+
} catch {
|
|
227
|
+
// ignore
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function tryGetDimensionsFromTag(imgTag) {
|
|
234
|
+
const widthMatch = imgTag.match(/\bwidth\s*=\s*(["']?)(\d+)\1/i);
|
|
235
|
+
const heightMatch = imgTag.match(/\bheight\s*=\s*(["']?)(\d+)\1/i);
|
|
236
|
+
const width = widthMatch ? Number(widthMatch[2]) : null;
|
|
237
|
+
const height = heightMatch ? Number(heightMatch[2]) : null;
|
|
238
|
+
if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
|
|
239
|
+
return { width, height };
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Extract alt text from img tag
|
|
246
|
+
*/
|
|
247
|
+
function extractAltText(imgTag) {
|
|
248
|
+
const altMatch = imgTag.match(/\balt\s*=\s*(["'])([^"']*)\1/i);
|
|
249
|
+
return altMatch ? altMatch[2] : "";
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Extract class from img tag
|
|
254
|
+
*/
|
|
255
|
+
function extractClass(imgTag) {
|
|
256
|
+
const classMatch = imgTag.match(/\bclass\s*=\s*(["'])([^"']*)\1/i);
|
|
257
|
+
return classMatch ? classMatch[2] : "";
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Build the img-preloader div container
|
|
262
|
+
*/
|
|
263
|
+
function buildPreloaderDiv(src, dims, alt, originalClass) {
|
|
264
|
+
const w = dims.width;
|
|
265
|
+
const h = dims.height;
|
|
266
|
+
const aspectRatio = (w / h).toFixed(6);
|
|
267
|
+
|
|
268
|
+
const classes = ["img-preloader"];
|
|
269
|
+
if (originalClass) {
|
|
270
|
+
classes.push(originalClass);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return `<div class="${classes.join(" ")}" ` +
|
|
274
|
+
`data-src="${escapeHtmlAttr(src)}" ` +
|
|
275
|
+
`data-width="${w}" ` +
|
|
276
|
+
`data-height="${h}" ` +
|
|
277
|
+
`data-alt="${escapeHtmlAttr(alt)}" ` +
|
|
278
|
+
`style="aspect-ratio: ${aspectRatio}; max-width: ${w}px;">` +
|
|
279
|
+
`<div class="img-preloader-skeleton"></div>` +
|
|
280
|
+
`</div>`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
hexo.extend.filter.register(
|
|
284
|
+
"after_post_render",
|
|
285
|
+
async function (data) {
|
|
286
|
+
const theme = hexo.theme.config;
|
|
287
|
+
if (!theme?.articles?.lazyload) return data;
|
|
288
|
+
if (!data || typeof data.content !== "string" || data.content.length === 0) return data;
|
|
289
|
+
|
|
290
|
+
const imgRegex = /<img\b[^>]*>/gim;
|
|
291
|
+
let result = "";
|
|
292
|
+
let lastIndex = 0;
|
|
293
|
+
let match;
|
|
294
|
+
|
|
295
|
+
while ((match = imgRegex.exec(data.content)) !== null) {
|
|
296
|
+
const imgTag = match[0];
|
|
297
|
+
const start = match.index;
|
|
298
|
+
const end = imgRegex.lastIndex;
|
|
299
|
+
result += data.content.slice(lastIndex, start);
|
|
300
|
+
lastIndex = end;
|
|
301
|
+
|
|
302
|
+
// Skip if marked with data-no-lazyload
|
|
303
|
+
if (/\bdata-no-lazyload\b/i.test(imgTag)) {
|
|
304
|
+
result += imgTag;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const srcMatch = imgTag.match(/\bsrc\s*=\s*(["'])([^"']*)\1/i);
|
|
309
|
+
if (!srcMatch) {
|
|
310
|
+
result += imgTag;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const originalSrc = srcMatch[2];
|
|
315
|
+
if (!originalSrc) {
|
|
316
|
+
result += imgTag;
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Skip data: URLs (already inline) and blob: URLs
|
|
321
|
+
if (originalSrc.startsWith("data:") || originalSrc.startsWith("blob:")) {
|
|
322
|
+
result += imgTag;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let dims = await getImageDimensions(originalSrc, imgTag, data);
|
|
327
|
+
if (!dims || !dims.width || !dims.height) {
|
|
328
|
+
dims = DEFAULT_FALLBACK_DIMENSIONS;
|
|
329
|
+
if (hexo?.log?.warn) {
|
|
330
|
+
hexo.log.warn(
|
|
331
|
+
`[redefine-x][lazyload] Unable to detect image size, fallback to ${dims.width}x${dims.height}: ${originalSrc}`,
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const alt = extractAltText(imgTag);
|
|
337
|
+
const originalClass = extractClass(imgTag);
|
|
338
|
+
|
|
339
|
+
// Replace <img> with <div class="img-preloader">
|
|
340
|
+
const preloaderDiv = buildPreloaderDiv(originalSrc, dims, alt, originalClass);
|
|
341
|
+
result += preloaderDiv;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
result += data.content.slice(lastIndex);
|
|
345
|
+
data.content = result;
|
|
346
|
+
|
|
347
|
+
return data;
|
|
348
|
+
},
|
|
349
|
+
1,
|
|
350
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const hbeTheme = `
|
|
2
|
+
<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="{{hbeWrongPassMessage}}" data-whm="{{hbeWrongHashMessage}}">
|
|
3
|
+
<script id="hbeData" type="hbeData" data-hmacdigest="{{hbeHmacDigest}}">{{hbeEncryptedData}}</script>
|
|
4
|
+
<div class="hbe hbe-content">
|
|
5
|
+
<div class="hbe hbe-input hbe-input-default">
|
|
6
|
+
<input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">
|
|
7
|
+
<label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">
|
|
8
|
+
<span class="hbe hbe-input-label-content hbe-input-label-content-default">{{hbeMessage}}</span>
|
|
9
|
+
</label>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
module.exports = { hbeTheme };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* main hexo */
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
hexo.extend.filter.register(
|
|
6
|
+
"after_post_render",
|
|
7
|
+
function (data) {
|
|
8
|
+
const theme = this.theme;
|
|
9
|
+
const config = this.config;
|
|
10
|
+
const url = new URL(config.url);
|
|
11
|
+
const siteHost = url.hostname || config.url;
|
|
12
|
+
|
|
13
|
+
// Match 'a' tags that don't contain html children.
|
|
14
|
+
const regPureATag = /<a([^>]*)href="([^"]*)"([^>]*)>([^<]*)<\/a>/gim;
|
|
15
|
+
|
|
16
|
+
data.content = data.content.replace(
|
|
17
|
+
regPureATag,
|
|
18
|
+
function (match, attrBegin, href, attrEnd, html) {
|
|
19
|
+
// Exit if the href attribute doesn't exists.
|
|
20
|
+
if (!href) return match;
|
|
21
|
+
|
|
22
|
+
let link = "";
|
|
23
|
+
try {
|
|
24
|
+
link = new URL(href);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
// Invalid url, e.g. Anchor link.
|
|
27
|
+
return match;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Exit if the url has same host with `config.url`, which means isn't an external link.
|
|
31
|
+
if (!link.protocol || link.hostname === siteHost) return match;
|
|
32
|
+
|
|
33
|
+
if (theme.config.articles.style.link_icon == false) {
|
|
34
|
+
return `<a class="link" ${attrBegin} href="${href}" ${attrEnd}>${html}</a>`;
|
|
35
|
+
} else {
|
|
36
|
+
return `<a class="link" ${attrBegin} href="${href}" ${attrEnd}>${html}<i class="fa-solid fa-arrow-up-right ml-[0.2em] font-light align-text-top text-[0.7em] link-icon"></i></a>`;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
0,
|
|
42
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
hexo.extend.filter.register('after_post_render', function(data) {
|
|
5
|
+
const tableRegex = /<table(?![\s\S]*?class=["'].*?\bgutter\b.*?["'])[\s\S]*?<\/table>/g;
|
|
6
|
+
const wrappedTable = match => `<div class="table-container">${match}</div>`;
|
|
7
|
+
data.content = data.content.replace(tableRegex, wrappedTable);
|
|
8
|
+
return data;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
*/
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
hexo.extend.helper.register('generateMeta', function (theme, page) {
|
|
2
|
+
const hexo = this;
|
|
3
|
+
let robots_content="";
|
|
4
|
+
if (page.robots) {
|
|
5
|
+
robots_content = page.robots
|
|
6
|
+
} else if (theme.seo && theme.seo.robots) {
|
|
7
|
+
if (hexo.is_home()) {
|
|
8
|
+
if (page.prev == 0) {
|
|
9
|
+
robots_content=theme.seo.robots.home_first_page
|
|
10
|
+
}else{
|
|
11
|
+
robots_content=theme.seo.robots.home_other_pages
|
|
12
|
+
}
|
|
13
|
+
} else if (hexo.is_archive()) {
|
|
14
|
+
robots_content=theme.seo.robots.archive
|
|
15
|
+
} else if (hexo.is_category()) {
|
|
16
|
+
robots_content=theme.seo.robots.category
|
|
17
|
+
} else if (hexo.is_tag()) {
|
|
18
|
+
robots_content=theme.seo.robots.tag
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if(robots_content){
|
|
22
|
+
return `<meta name="robots" content="${robots_content}">`
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* hexo-auto-canonical
|
|
28
|
+
* https://github.com/hyunseob/hexo-auto-canonical.git
|
|
29
|
+
* Copyright (c) 2015, HyunSeob
|
|
30
|
+
* Licensed under the MIT license.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
hexo.extend.helper.register('autoCanonical', function (config, page) {
|
|
34
|
+
var base_url = config.url;
|
|
35
|
+
if (config.url.charAt(config.url.length - 1) !== '/') base_url += '/';
|
|
36
|
+
|
|
37
|
+
return '<link rel="canonical" href="' + base_url + page.canonical_path.replace('index.html', '').toLowerCase() + '"/>';
|
|
38
|
+
});
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/*
|
|
2
|
+
pageData is an object that defines various page types and their associated rendering details.
|
|
3
|
+
|
|
4
|
+
Each page type includes the following properties:
|
|
5
|
+
|
|
6
|
+
- titles: An array of possible titles for the page, which are used to identify the page type.
|
|
7
|
+
- types: An array of page types that can be matched; the type takes precedence over the title for identification.
|
|
8
|
+
- partial: The path to the partial template that will be used to render the content of the page.
|
|
9
|
+
- layout: Specifies the layout style for the page. "raw" indicates that no theme layout will be applied, while "default" means the standard theme layout (container) will be used.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const pageData = {
|
|
13
|
+
home: {
|
|
14
|
+
titles: ["home", "首页"],
|
|
15
|
+
types: ["home"],
|
|
16
|
+
partial: "pages/home/home-content",
|
|
17
|
+
layout: "raw",
|
|
18
|
+
},
|
|
19
|
+
archive: {
|
|
20
|
+
titles: ["archive", "归档"],
|
|
21
|
+
types: ["archive", "archives"],
|
|
22
|
+
partial: "pages/archive/archive",
|
|
23
|
+
layout: "raw",
|
|
24
|
+
},
|
|
25
|
+
post: {
|
|
26
|
+
titles: ["post", "文章"],
|
|
27
|
+
types: ["post", "posts"],
|
|
28
|
+
partial: "pages/post/article-content",
|
|
29
|
+
layout: "raw",
|
|
30
|
+
},
|
|
31
|
+
categories: {
|
|
32
|
+
titles: ["category", "categories"],
|
|
33
|
+
types: ["category", "categories"],
|
|
34
|
+
partial: "pages/category/categories",
|
|
35
|
+
layout: "default",
|
|
36
|
+
},
|
|
37
|
+
categoryDetail: {
|
|
38
|
+
titles: [],
|
|
39
|
+
types: [],
|
|
40
|
+
partial: "pages/category/category-detail",
|
|
41
|
+
layout: "default",
|
|
42
|
+
},
|
|
43
|
+
tags: {
|
|
44
|
+
titles: ["tag", "tags"],
|
|
45
|
+
types: ["tag", "tags"],
|
|
46
|
+
partial: "pages/tag/tags",
|
|
47
|
+
layout: "default",
|
|
48
|
+
},
|
|
49
|
+
tagDetail: {
|
|
50
|
+
titles: [],
|
|
51
|
+
types: [],
|
|
52
|
+
partial: "pages/tag/tag-detail",
|
|
53
|
+
layout: "default",
|
|
54
|
+
},
|
|
55
|
+
notFound: {
|
|
56
|
+
titles: ["404", "notfound"],
|
|
57
|
+
types: ["404", "notfound"],
|
|
58
|
+
partial: "pages/notfound/notfound",
|
|
59
|
+
layout: "raw",
|
|
60
|
+
},
|
|
61
|
+
friends: {
|
|
62
|
+
titles: ["friends", "links", "link", "friend", "友情链接"],
|
|
63
|
+
types: ["links", "link"],
|
|
64
|
+
partial: "pages/friends/friends-link",
|
|
65
|
+
layout: "default",
|
|
66
|
+
},
|
|
67
|
+
shuoshuo: {
|
|
68
|
+
titles: ["shuoshuo", "说说"],
|
|
69
|
+
types: ["essays", "essay", "shuoshuo"],
|
|
70
|
+
partial: "pages/shuoshuo/essays",
|
|
71
|
+
layout: "default",
|
|
72
|
+
},
|
|
73
|
+
masonry: {
|
|
74
|
+
titles: ["gallery", "瀑布流", "相册", "photos", "photo"],
|
|
75
|
+
types: ["masonry", "gallery", "瀑布流", "相册", "photos", "photo"],
|
|
76
|
+
partial: "pages/masonry/masonry",
|
|
77
|
+
layout: "default",
|
|
78
|
+
},
|
|
79
|
+
bookmarks: {
|
|
80
|
+
titles: [],
|
|
81
|
+
types: ["bookmarks", "bookmark", "tools"],
|
|
82
|
+
partial: "pages/bookmarks/bookmarks",
|
|
83
|
+
layout: "raw",
|
|
84
|
+
},
|
|
85
|
+
pageTemplate: {
|
|
86
|
+
titles: [],
|
|
87
|
+
types: [],
|
|
88
|
+
partial: "pages/page-template",
|
|
89
|
+
layout: "default",
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
hexo.extend.helper.register("getAllPageData", function () {
|
|
94
|
+
return pageData;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
hexo.extend.helper.register("getPageData", function (page) {
|
|
98
|
+
if (this.is_home()) return pageData.home;
|
|
99
|
+
if (this.is_archive()) return pageData.archive;
|
|
100
|
+
if (this.is_post()) return pageData.post;
|
|
101
|
+
if (this.is_category()) return pageData.categoryDetail;
|
|
102
|
+
if (this.is_tag()) return pageData.tagDetail;
|
|
103
|
+
|
|
104
|
+
const currentPageConfig = Object.entries(pageData).find(([type, config]) => {
|
|
105
|
+
return config.types.includes(page.template || page.type) || config.titles.includes(page.title?.toLowerCase());
|
|
106
|
+
});
|
|
107
|
+
return currentPageConfig ? pageData[currentPageConfig[0]] : null;
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
hexo.extend.helper.register("getPagePartialPath", function (page) {
|
|
111
|
+
const matchesPageType = (type) => {
|
|
112
|
+
const config = pageData[type];
|
|
113
|
+
return (
|
|
114
|
+
config.types.includes(page.template || page.type) ||
|
|
115
|
+
config.titles.includes(page.title?.toLowerCase())
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Check built-in page types first
|
|
120
|
+
if (this.is_home()) return pageData.home.partial;
|
|
121
|
+
|
|
122
|
+
if (this.is_post()) return pageData.post.partial;
|
|
123
|
+
// Check custom page types
|
|
124
|
+
for (const [type, config] of Object.entries(pageData)) {
|
|
125
|
+
if (matchesPageType(type) && config.layout === "raw") {
|
|
126
|
+
return config.partial;
|
|
127
|
+
} else if (this.is_archive() && pageData.archive.layout === "raw") { // return raw layout for archive page
|
|
128
|
+
return pageData.archive.partial;
|
|
129
|
+
} else if (this.is_category() && pageData.categoryDetail.layout === "raw") { // return raw layout for category page
|
|
130
|
+
return pageData.categoryDetail.partial;
|
|
131
|
+
} else if (this.is_tag() && pageData.tagDetail.layout === "raw") { // return raw layout for tag page
|
|
132
|
+
return pageData.tagDetail.partial;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return pageData.pageTemplate.partial;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
hexo.extend.helper.register("getPageTitle", function (page) {
|
|
140
|
+
const pageData = this.getPageData(page);
|
|
141
|
+
let type = null;
|
|
142
|
+
|
|
143
|
+
// Determine the type based on page properties
|
|
144
|
+
if (this.is_home()) type = "home";
|
|
145
|
+
else if (this.is_archive()) type = "archive";
|
|
146
|
+
else if (this.is_post()) type = "post";
|
|
147
|
+
else {
|
|
148
|
+
type = pageData.type;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// const config = type ? pageData[type] : null;
|
|
152
|
+
return page.title || this.__(type) || "Untitled";
|
|
153
|
+
});
|