hexo-theme-gnix 9.0.0 → 11.0.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.
- package/README.md +4 -6
- package/include/hexo/feed.js +5 -5
- package/include/hexo/filter.js +25 -1
- package/include/hexo/generator/archive.js +116 -0
- package/include/hexo/generator/home.js +64 -0
- package/include/hexo/generator/index.js +82 -0
- package/include/hexo/generator/md_generator.js +87 -0
- package/include/hexo/generator/page.js +55 -0
- package/include/hexo/generator/tag.js +84 -0
- package/include/hexo/helper.js +38 -0
- package/include/hexo/i18n.js +183 -0
- package/include/hexo/renderer.js +131 -0
- package/include/util/article_font.js +132 -0
- package/include/util/i18n.js +280 -0
- package/include/util/theme.js +84 -0
- package/languages/en.yml +28 -0
- package/languages/zh-CN.yml +28 -0
- package/layout/archive.jsx +131 -127
- package/layout/common/article.jsx +283 -16
- package/layout/common/article_info.jsx +339 -0
- package/layout/common/article_media.jsx +11 -4
- package/layout/common/comment.jsx +15 -7
- package/layout/common/footer.jsx +6 -5
- package/layout/common/head.jsx +121 -32
- package/layout/common/navbar.jsx +195 -65
- package/layout/common/theme_selector.jsx +16 -14
- package/layout/layout.jsx +43 -5
- package/layout/misc/open_graph.jsx +162 -66
- package/layout/misc/paginator.jsx +2 -8
- package/layout/plugin/cookie_consent.jsx +252 -53
- package/layout/plugin/swup.jsx +1 -1
- package/layout/search/insight.jsx +1 -1
- package/layout/tag.jsx +3 -2
- package/layout/tags.jsx +81 -73
- package/package.json +18 -5
- package/scripts/index.js +1 -0
- package/source/css/archive.css +225 -180
- package/source/css/default.css +1162 -98
- package/source/css/responsive.css +426 -0
- package/source/css/shiki/shiki.css +12 -2081
- package/source/css/tags.css +183 -0
- package/source/css/twikoo.css +1049 -1045
- package/source/img/favicon.svg +1 -6
- package/source/img/og_image.webp +0 -0
- package/source/js/article-font-utils.js +99 -0
- package/source/js/busuanzi.js +91 -24
- package/source/js/components/chat.js +169 -50
- package/source/js/components/image-carousel.js +152 -108
- package/source/js/components/sidenote.js +210 -0
- package/source/js/components/text-image-section.js +78 -90
- package/source/js/components/theme-stacked.js +65 -33
- package/source/js/components/tree.js +30 -16
- package/source/js/decrypt.js +7 -2
- package/source/js/main.js +428 -5
- package/source/js/swup.js +39 -0
- package/source/js/theme-selector.js +26 -16
- package/include/hexo/generator.js +0 -53
- package/layout/misc/article_licensing.jsx +0 -99
- package/source/css/responsive/desktop.css +0 -36
- package/source/css/responsive/mobile.css +0 -29
- package/source/css/responsive/tablet.css +0 -43
- package/source/css/responsive/touch.css +0 -155
- package/source/img/logo.svg +0 -9
- package/source/js/archive-breadcrumb.js +0 -132
- package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.css +0 -6
- package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.js +0 -1
- package/source/js/swup.bundle.js +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
const { extname } = require("node:path");
|
|
2
|
+
const createPostProcessor = require("hexo/dist/plugins/processor/post");
|
|
3
|
+
const { isHiddenFile, isMatch, isTmpFile } = require("hexo/dist/plugins/processor/common");
|
|
4
|
+
const {
|
|
5
|
+
getI18nKey,
|
|
6
|
+
getLanguageBasePath,
|
|
7
|
+
getLanguage,
|
|
8
|
+
getLanguageKeys,
|
|
9
|
+
getPageLanguageKey,
|
|
10
|
+
inferI18nKeyFromSource,
|
|
11
|
+
isI18nEnabled,
|
|
12
|
+
localizePath,
|
|
13
|
+
trimSlashes,
|
|
14
|
+
} = require("../util/i18n");
|
|
15
|
+
|
|
16
|
+
function getConfig(hexo, locals = {}) {
|
|
17
|
+
return Object.assign({}, hexo.config, hexo.config.theme_config, hexo.theme.config, locals.theme);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function getLocalizedPostParams(hexo, sourcePath) {
|
|
21
|
+
const config = getConfig(hexo);
|
|
22
|
+
if (!isI18nEnabled(config) || isTmpFile(sourcePath)) return null;
|
|
23
|
+
|
|
24
|
+
const match = sourcePath.replace(/\\/g, "/").match(/^([^/]+)\/(_posts|_drafts)\/(.+)$/);
|
|
25
|
+
if (!match) return null;
|
|
26
|
+
|
|
27
|
+
const langKey = match[1];
|
|
28
|
+
if (!getLanguageKeys(config).includes(langKey)) return null;
|
|
29
|
+
|
|
30
|
+
const postPath = match[3];
|
|
31
|
+
if (isHiddenFile(postPath)) return null;
|
|
32
|
+
|
|
33
|
+
let renderable = hexo.render.isRenderable(sourcePath) && !isMatch(sourcePath, hexo.config.skip_render);
|
|
34
|
+
if (renderable && hexo.config.post_asset_folder) {
|
|
35
|
+
renderable = extname(hexo.config.new_post_name) === extname(sourcePath);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
i18n_lang: langKey,
|
|
40
|
+
path: postPath,
|
|
41
|
+
published: match[2] === "_posts",
|
|
42
|
+
renderable,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function getLocalizedPageParams(hexo, sourcePath) {
|
|
47
|
+
const config = getConfig(hexo);
|
|
48
|
+
if (!isI18nEnabled(config) || isTmpFile(sourcePath)) return null;
|
|
49
|
+
|
|
50
|
+
const normalized = sourcePath.replace(/\\/g, "/");
|
|
51
|
+
const match = normalized.match(/^([^/]+)\/(.+)$/);
|
|
52
|
+
if (!match) return null;
|
|
53
|
+
|
|
54
|
+
const langKey = match[1];
|
|
55
|
+
if (!getLanguageKeys(config).includes(langKey)) return null;
|
|
56
|
+
|
|
57
|
+
const pagePath = match[2];
|
|
58
|
+
if (pagePath.startsWith("_posts/") || pagePath.startsWith("_drafts/") || isHiddenFile(pagePath)) return null;
|
|
59
|
+
|
|
60
|
+
const renderable = hexo.render.isRenderable(sourcePath) && !isMatch(sourcePath, hexo.config.skip_render);
|
|
61
|
+
if (!renderable) return null;
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
i18n_lang: langKey,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildPostI18nUpdate(post, langKey, config) {
|
|
69
|
+
const language = getLanguage(config, langKey);
|
|
70
|
+
const update = {
|
|
71
|
+
i18n_path: getLanguageBasePath(config, langKey),
|
|
72
|
+
i18n_lang: langKey,
|
|
73
|
+
lang: language.locale,
|
|
74
|
+
language: language.locale,
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
if (!post.i18n_key) {
|
|
78
|
+
update.i18n_key = getI18nKey(post) || inferI18nKeyFromSource(post.source);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { $set: update };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getLocalizedPagePath(page, langKey, config) {
|
|
85
|
+
const sourcePrefix = `${trimSlashes(langKey)}/`;
|
|
86
|
+
let route = page.path || "";
|
|
87
|
+
|
|
88
|
+
if (route.startsWith(sourcePrefix)) {
|
|
89
|
+
route = route.slice(sourcePrefix.length);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return trimSlashes(localizePath(`/${route}`, langKey, config));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function buildPageI18nUpdate(page, langKey, config) {
|
|
96
|
+
const language = getLanguage(config, langKey);
|
|
97
|
+
const update = {
|
|
98
|
+
i18n_path: getLanguageBasePath(config, langKey),
|
|
99
|
+
i18n_lang: langKey,
|
|
100
|
+
lang: language.locale,
|
|
101
|
+
language: language.locale,
|
|
102
|
+
path: getLocalizedPagePath(page, langKey, config),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (!page.i18n_key) {
|
|
106
|
+
update.i18n_key = getI18nKey(page) || inferI18nKeyFromSource(page.source);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return { $set: update };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = (hexo) => {
|
|
113
|
+
const defaultPostProcessor = createPostProcessor(hexo);
|
|
114
|
+
|
|
115
|
+
hexo.extend.processor.register(
|
|
116
|
+
(sourcePath) => getLocalizedPostParams(hexo, sourcePath),
|
|
117
|
+
(file) =>
|
|
118
|
+
Promise.resolve(defaultPostProcessor.process(file)).then(() => {
|
|
119
|
+
if (!isI18nEnabled(getConfig(hexo))) return null;
|
|
120
|
+
if (!file.params.renderable) return null;
|
|
121
|
+
|
|
122
|
+
const post = hexo.model("Post").findOne({ source: file.path });
|
|
123
|
+
if (!post) return null;
|
|
124
|
+
|
|
125
|
+
return post.update(buildPostI18nUpdate(post, file.params.i18n_lang, getConfig(hexo)));
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
hexo.extend.processor.register(
|
|
130
|
+
(sourcePath) => getLocalizedPageParams(hexo, sourcePath),
|
|
131
|
+
(file) => {
|
|
132
|
+
if (!isI18nEnabled(getConfig(hexo))) return null;
|
|
133
|
+
if (file.type === "delete") return null;
|
|
134
|
+
|
|
135
|
+
const page = hexo.model("Page").findOne({ source: file.path });
|
|
136
|
+
if (!page) return null;
|
|
137
|
+
|
|
138
|
+
return page.update(buildPageI18nUpdate(page, file.params.i18n_lang, getConfig(hexo)));
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
hexo.extend.filter.register(
|
|
143
|
+
"post_permalink",
|
|
144
|
+
(post) => {
|
|
145
|
+
if (!post || typeof post !== "object") return post;
|
|
146
|
+
const activeConfig = getConfig(hexo);
|
|
147
|
+
if (!isI18nEnabled(activeConfig)) return post;
|
|
148
|
+
|
|
149
|
+
const langKey = getPageLanguageKey(post, activeConfig);
|
|
150
|
+
const language = getLanguage(activeConfig, langKey);
|
|
151
|
+
|
|
152
|
+
post.i18n_lang = post.i18n_lang || langKey;
|
|
153
|
+
post.i18n_path = getLanguageBasePath(activeConfig, langKey);
|
|
154
|
+
post.lang = language.locale;
|
|
155
|
+
post.language = language.locale;
|
|
156
|
+
post.i18n_key = post.i18n_key || getI18nKey(post) || inferI18nKeyFromSource(post.source);
|
|
157
|
+
|
|
158
|
+
return post;
|
|
159
|
+
},
|
|
160
|
+
5,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
hexo.extend.filter.register(
|
|
164
|
+
"template_locals",
|
|
165
|
+
(locals) => {
|
|
166
|
+
const page = locals.page;
|
|
167
|
+
const activeConfig = getConfig(hexo, locals);
|
|
168
|
+
if (!page || !isI18nEnabled(activeConfig)) return locals;
|
|
169
|
+
|
|
170
|
+
const langKey = getPageLanguageKey(page, activeConfig);
|
|
171
|
+
const language = getLanguage(activeConfig, langKey);
|
|
172
|
+
|
|
173
|
+
page.i18n_lang = page.i18n_lang || langKey;
|
|
174
|
+
page.i18n_path = getLanguageBasePath(activeConfig, langKey);
|
|
175
|
+
page.lang = language.locale;
|
|
176
|
+
page.language = language.locale;
|
|
177
|
+
page.i18n_key = page.i18n_key || getI18nKey(page) || inferI18nKeyFromSource(page.source);
|
|
178
|
+
|
|
179
|
+
return locals;
|
|
180
|
+
},
|
|
181
|
+
5,
|
|
182
|
+
);
|
|
183
|
+
};
|
package/include/hexo/renderer.js
CHANGED
|
@@ -1,3 +1,129 @@
|
|
|
1
|
+
const path = require("node:path");
|
|
2
|
+
const { tab } = require("@mdit/plugin-tab");
|
|
3
|
+
const { createMarkdownExit } = require("markdown-exit");
|
|
4
|
+
const mermaidDiagram = require("markdown-exit-mermaid");
|
|
5
|
+
const ratex = require("markdown-exit-ratex");
|
|
6
|
+
const code = require("markdown-exit-shiki");
|
|
7
|
+
const abbr = require("markdown-it-abbr");
|
|
8
|
+
const anchor = require("markdown-it-anchor");
|
|
9
|
+
const footnote = require("markdown-it-footnote");
|
|
10
|
+
const ins = require("markdown-it-ins");
|
|
11
|
+
const mark = require("markdown-it-mark");
|
|
12
|
+
const sub = require("markdown-it-sub");
|
|
13
|
+
const sup = require("markdown-it-sup");
|
|
14
|
+
const taskLists = require("markdown-it-task-lists");
|
|
15
|
+
|
|
16
|
+
function resolveDefault(module) {
|
|
17
|
+
return module && typeof module === "object" && "default" in module ? module.default : module;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
class MarkdownRenderer {
|
|
21
|
+
constructor(hexo) {
|
|
22
|
+
this.hexo = hexo;
|
|
23
|
+
this.config = {
|
|
24
|
+
render_options: {
|
|
25
|
+
breaks: true,
|
|
26
|
+
html: true,
|
|
27
|
+
langPrefix: "language-",
|
|
28
|
+
linkify: true,
|
|
29
|
+
quotes: "“”‘’",
|
|
30
|
+
typographer: true,
|
|
31
|
+
xhtmlOut: false,
|
|
32
|
+
},
|
|
33
|
+
code_options: {
|
|
34
|
+
themes: {
|
|
35
|
+
light: "catppuccin-latte",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
mermaid_options: {
|
|
39
|
+
theme: "default",
|
|
40
|
+
},
|
|
41
|
+
...(hexo.config.markdown_exit || {}),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
this.md = createMarkdownExit(this.config.render_options);
|
|
45
|
+
this.initPlugins();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
initPlugins() {
|
|
49
|
+
console.time("MarkdownExit: Load Default Plugins");
|
|
50
|
+
if (this.config.defaultPlugins !== false) {
|
|
51
|
+
this.md
|
|
52
|
+
.use(resolveDefault(footnote))
|
|
53
|
+
.use(resolveDefault(mark))
|
|
54
|
+
.use(resolveDefault(sub))
|
|
55
|
+
.use(resolveDefault(sup))
|
|
56
|
+
.use(resolveDefault(abbr))
|
|
57
|
+
.use(resolveDefault(ins))
|
|
58
|
+
.use(resolveDefault(taskLists))
|
|
59
|
+
.use(resolveDefault(code), this.config.code_options)
|
|
60
|
+
.use(resolveDefault(mermaidDiagram), this.config.mermaid_options)
|
|
61
|
+
.use(resolveDefault(ratex), this.config.ratex_options)
|
|
62
|
+
.use(tab)
|
|
63
|
+
.use(resolveDefault(anchor), {
|
|
64
|
+
permalink: resolveDefault(anchor).permalink.headerLink(),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
console.timeEnd("MarkdownExit: Load Default Plugins");
|
|
68
|
+
|
|
69
|
+
console.time("MarkdownExit: Load User Plugins");
|
|
70
|
+
this.loadUserPlugins();
|
|
71
|
+
console.timeEnd("MarkdownExit: Load User Plugins");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
resolvePluginFunction(plugin) {
|
|
75
|
+
if (plugin && typeof plugin.default === "function") return plugin.default;
|
|
76
|
+
if (typeof plugin === "function") return plugin;
|
|
77
|
+
|
|
78
|
+
if (plugin && typeof plugin === "object") {
|
|
79
|
+
for (const key in plugin) {
|
|
80
|
+
if (typeof plugin[key] === "function") return plugin[key];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return plugin;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
loadUserPlugins() {
|
|
88
|
+
const plugins = this.config.plugins || [];
|
|
89
|
+
for (const pluginConfig of plugins) {
|
|
90
|
+
const isString = typeof pluginConfig === "string";
|
|
91
|
+
const pluginName = isString ? pluginConfig : pluginConfig.name;
|
|
92
|
+
const pluginOptions = isString ? {} : pluginConfig.options || {};
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const pluginPath = path.join(this.hexo.base_dir, "node_modules", pluginName);
|
|
96
|
+
const plugin = require(pluginPath);
|
|
97
|
+
const pluginFn = this.resolvePluginFunction(plugin);
|
|
98
|
+
|
|
99
|
+
this.md.use(pluginFn, pluginOptions);
|
|
100
|
+
if (process.env.DEBUG) {
|
|
101
|
+
console.log(`Successfully loaded plugin: ${pluginName}`);
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.warn(`Failed to load plugin: ${pluginName}`);
|
|
105
|
+
if (process.env.DEBUG) {
|
|
106
|
+
console.warn(` Error: ${error}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async render(data) {
|
|
113
|
+
if (!data.text) return "";
|
|
114
|
+
return this.md.renderAsync(data.text);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const markdownRendererInstances = new WeakMap();
|
|
119
|
+
|
|
120
|
+
function getMarkdownRenderer(hexo) {
|
|
121
|
+
if (!markdownRendererInstances.has(hexo)) {
|
|
122
|
+
markdownRendererInstances.set(hexo, new MarkdownRenderer(hexo));
|
|
123
|
+
}
|
|
124
|
+
return markdownRendererInstances.get(hexo);
|
|
125
|
+
}
|
|
126
|
+
|
|
1
127
|
const { transformSync } = require("esbuild");
|
|
2
128
|
const { createElement } = require("inferno-create-element");
|
|
3
129
|
const { renderToStaticMarkup } = require("inferno-server");
|
|
@@ -50,5 +176,10 @@ function renderer(data, locals) {
|
|
|
50
176
|
renderer.compile = compile;
|
|
51
177
|
|
|
52
178
|
module.exports = (hexo) => {
|
|
179
|
+
const markdownConfig = hexo.config.markdown_exit || {};
|
|
180
|
+
const markdownRenderer = async (data) => getMarkdownRenderer(hexo).render(data);
|
|
181
|
+
markdownRenderer.disableNunjucks = Boolean(markdownConfig.disableNunjucks);
|
|
182
|
+
|
|
183
|
+
hexo.extend.renderer.register("md", "html", markdownRenderer);
|
|
53
184
|
hexo.extend.renderer.register("jsx", "html", renderer, true);
|
|
54
185
|
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const STORAGE_KEY = "gnix-article-font";
|
|
2
|
+
|
|
3
|
+
const DEFAULT_SETTINGS = Object.freeze({
|
|
4
|
+
size: "medium",
|
|
5
|
+
type: "serif",
|
|
6
|
+
lineHeight: 1.7,
|
|
7
|
+
weight: "regular",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const SIZE_OPTIONS = Object.freeze(["small", "medium-small", "medium", "medium-large", "large"]);
|
|
11
|
+
const FONT_OPTIONS = Object.freeze(["serif", "sans-serif", "mono", "handwriting"]);
|
|
12
|
+
const WEIGHT_OPTIONS = Object.freeze(["light", "regular", "medium"]);
|
|
13
|
+
const LINE_HEIGHT = Object.freeze({
|
|
14
|
+
min: 1.45,
|
|
15
|
+
max: 1.9,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const CUSTOM_FONT_FAMILY_OPTIONS = Object.freeze({
|
|
19
|
+
serif: "--font-serif",
|
|
20
|
+
"sans-serif": "--font-sans-serif",
|
|
21
|
+
mono: "--font-mono",
|
|
22
|
+
handwriting: "--font-handwriting",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const CUSTOM_FONT_IMPORT_LIMIT = 6;
|
|
26
|
+
|
|
27
|
+
function getClientArticleFontConfig() {
|
|
28
|
+
return {
|
|
29
|
+
storageKey: STORAGE_KEY,
|
|
30
|
+
defaultSettings: DEFAULT_SETTINGS,
|
|
31
|
+
sizeOptions: SIZE_OPTIONS,
|
|
32
|
+
fontOptions: FONT_OPTIONS,
|
|
33
|
+
weightOptions: WEIGHT_OPTIONS,
|
|
34
|
+
lineHeight: LINE_HEIGHT,
|
|
35
|
+
customFonts: {
|
|
36
|
+
familyOptions: CUSTOM_FONT_FAMILY_OPTIONS,
|
|
37
|
+
importLimit: CUSTOM_FONT_IMPORT_LIMIT,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function stringifyForScript(value) {
|
|
43
|
+
return JSON.stringify(value)
|
|
44
|
+
.replace(/</g, "\\u003c")
|
|
45
|
+
.replace(/\u2028/g, "\\u2028")
|
|
46
|
+
.replace(/\u2029/g, "\\u2029");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getArticleFontInitScript() {
|
|
50
|
+
const config = stringifyForScript(getClientArticleFontConfig());
|
|
51
|
+
|
|
52
|
+
return `
|
|
53
|
+
(function() {
|
|
54
|
+
var config = ${config};
|
|
55
|
+
var defaults = config.defaultSettings || {};
|
|
56
|
+
var stored = null;
|
|
57
|
+
var parsed = {};
|
|
58
|
+
var utils = window.__GNIX_ARTICLE_FONT_UTILS__ || {};
|
|
59
|
+
|
|
60
|
+
window.__GNIX_ARTICLE_FONT_CONFIG__ = config;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
stored = localStorage.getItem(config.storageKey);
|
|
64
|
+
} catch (_) {}
|
|
65
|
+
|
|
66
|
+
if (stored) {
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(stored) || {};
|
|
69
|
+
} catch (_) {}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function hasOption(options, value) {
|
|
73
|
+
return Array.isArray(options) && options.indexOf(value) !== -1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function normalizeLineHeight(value) {
|
|
77
|
+
if (value === "compact") return 1.55;
|
|
78
|
+
if (value === "normal") return 1.7;
|
|
79
|
+
if (value === "relaxed") return 1.85;
|
|
80
|
+
|
|
81
|
+
var parsedValue = Number(value);
|
|
82
|
+
var min = Number(config.lineHeight && config.lineHeight.min);
|
|
83
|
+
var max = Number(config.lineHeight && config.lineHeight.max);
|
|
84
|
+
var fallback = Number(defaults.lineHeight);
|
|
85
|
+
|
|
86
|
+
if (!Number.isFinite(parsedValue)) parsedValue = Number.isFinite(fallback) ? fallback : 1.7;
|
|
87
|
+
if (!Number.isFinite(min)) min = 1.45;
|
|
88
|
+
if (!Number.isFinite(max)) max = 1.9;
|
|
89
|
+
|
|
90
|
+
return Math.min(max, Math.max(min, parsedValue));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var candidate = Object.assign({}, defaults, parsed);
|
|
94
|
+
var customFonts = utils.normalizeCustomFonts
|
|
95
|
+
? utils.normalizeCustomFonts(
|
|
96
|
+
candidate.customFonts,
|
|
97
|
+
config.customFonts && config.customFonts.familyOptions,
|
|
98
|
+
config.customFonts && config.customFonts.importLimit
|
|
99
|
+
)
|
|
100
|
+
: { imports: [], families: {} };
|
|
101
|
+
var settings = {
|
|
102
|
+
size: hasOption(config.sizeOptions, candidate.size) ? candidate.size : defaults.size,
|
|
103
|
+
type: hasOption(config.fontOptions, candidate.type) ? candidate.type : defaults.type,
|
|
104
|
+
lineHeight: normalizeLineHeight(candidate.lineHeight),
|
|
105
|
+
weight: hasOption(config.weightOptions, candidate.weight) ? candidate.weight : defaults.weight,
|
|
106
|
+
customFonts: customFonts
|
|
107
|
+
};
|
|
108
|
+
var html = document.documentElement;
|
|
109
|
+
|
|
110
|
+
if (utils.applyCustomFontImports) utils.applyCustomFontImports(settings.customFonts.imports);
|
|
111
|
+
if (utils.applyCustomFontFamilies) utils.applyCustomFontFamilies(html, settings.customFonts.families, config.customFonts && config.customFonts.familyOptions);
|
|
112
|
+
html.setAttribute("data-article-font-size", settings.size);
|
|
113
|
+
html.setAttribute("data-article-font-family", settings.type);
|
|
114
|
+
html.setAttribute("data-article-line-height", String(settings.lineHeight));
|
|
115
|
+
html.setAttribute("data-article-font-weight", settings.weight);
|
|
116
|
+
html.style.setProperty("--article-line-height", String(settings.lineHeight));
|
|
117
|
+
})();
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
CUSTOM_FONT_FAMILY_OPTIONS,
|
|
123
|
+
CUSTOM_FONT_IMPORT_LIMIT,
|
|
124
|
+
DEFAULT_SETTINGS,
|
|
125
|
+
FONT_OPTIONS,
|
|
126
|
+
LINE_HEIGHT,
|
|
127
|
+
SIZE_OPTIONS,
|
|
128
|
+
STORAGE_KEY,
|
|
129
|
+
WEIGHT_OPTIONS,
|
|
130
|
+
getArticleFontInitScript,
|
|
131
|
+
getClientArticleFontConfig,
|
|
132
|
+
};
|