Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ defaults:
path: ""
values:
layout: document
read_time: false
author_profile: false
share: false
comments: false
show_date: true
sidebar:
nav: docs
hits: true
Expand Down
32 changes: 16 additions & 16 deletions _data/settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,19 @@ appearance_color:
- light
- dark
- auto
appearance_skin_light:
appearance_color_switcher:
type: radio
default: default
default: enable
options:
- enable
- disable
appearance_skin:
type: multi-radio
children:
light:
default: default
dark:
default: dark
options:
- default
- air
Expand All @@ -21,19 +31,9 @@ appearance_skin_light:
- sunrise
- catppuccin_latte
- catppuccin_mocha
appearance_skin_dark:
miscellaneous_hits:
type: radio
default: dark
default: enable
options:
- default
- air
- aqua
- contrast
- dark
- dirt
- neon
- mint
- plum
- sunrise
- catppuccin_latte
- catppuccin_mocha
- enable
- disable
2 changes: 1 addition & 1 deletion _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<body class="layout--{{ page.layout | default: layout.layout }}{% if page.classes or layout.classes %}{{ page.classes | default: layout.classes | join: ' ' | prepend: ' ' }}{% endif %}" dir="{% if site.rtl %}rtl{% else %}ltr{% endif %}">
{% if site.preview and site.preview.pr-number %}
<div class="notice--warning text-center m0" style="position: sticky; top: 0; z-index: 999; padding: 0.4em;">当前站点为预览构建而非官方文档。如需反馈问题,请前往 <a href="https://github.com/HMCL-dev/HMCL-docs/pull/{{ site.preview.pr-number }}">#{{ site.preview.pr-number }}</a> 留言。</div>
<div class="notice--warning text-center preview">当前站点为预览构建而非官方文档。如需反馈问题,请前往 <a href="https://github.com/HMCL-dev/HMCL-docs/pull/{{ site.preview.pr-number }}">#{{ site.preview.pr-number }}</a> 留言。</div>
{% endif %}

{% include_cached skip-links.html locale=locale %}
Expand Down
17 changes: 9 additions & 8 deletions _layouts/document.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
layout: single
---

{% if jekyll.environment == 'production' and page.hits %}
<img src="https://hits.zkitefly.eu.org/?tag={{ page.url | absolute_url | url_encode }}" alt="Hits" decoding="async">
{% endif %}

<div class="notice--info">
<p>本文由 {{ page.author | default: '未署名用户' }} 创建{% if page.contributors %},并由 {{ page.contributors | join: ' ' }} 编辑{% endif %}。</p>
</div>

{{ content }}

{% if page.author or page.contributors or jekyll.environment == 'production' and page.hits %}
<script src="{{ '/assets/js/meta.js' | relative_url }}"></script>
<script>
{%- if page.author %}appendMeta("{{ page.author }}", "fas fa-user-pen");{% endif -%}
{%- for contributor in page.contributors %}appendMeta("{{ contributor }}", "fas fa-user-pen");{% endfor -%}
{%- if jekyll.environment == 'production' and page.hits %}hits("{{ page.url | absolute_url | url_encode }}");{% endif -%}
</script>
{% endif %}
77 changes: 43 additions & 34 deletions _layouts/settings.html
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
---
layout: document
layout: single
---

{% for group in page.data %}

{% capture notice %}

## {{ group.title }}

{%- for group in page.data %}
<h2 id="{{ group.title }}">{{ group.title }}</h2>
{% for pair in group.settings %}
{% assign name = pair[0] %}
{% assign value = pair[1] %}
{% assign setting = site.data.settings[name] %}

{% if setting.type == 'radio' %}
<div class="notice">
<ul class="task-list">
<li><strong>{{ value.title }}</strong></li>
<li>{{ value.description }}</li>
{% for option in setting.options %}
<li class="task-list-item">
<input type="radio" class="task-list-item-checkbox" name="{{ name }}" value="{{ option }}" id="{{ name }}_{{ option }}"{% if setting.default == option %} checked{% endif %}><label for="{{ name }}_{{ option }}">{{ value.options[option] }}</label>
</li>
{% endfor %}
</ul>
<h3 id="{{ group.title }}-{{ name }}">{{ value.title }}</h3>
{% if value.description %}<p>{{ value.description }}</p>{% endif %}
{% if setting.type == 'radio' %}
{% for option in setting.options %}
<label>
<input type="radio"{% if setting.default == option %} checked{% endif %} class="setting-item" name="{{ name }}" value="{{ option }}">
{{ value.options[option] }}
</label>
{% endfor %}
{% elsif setting.type == 'multi-radio' %}
<table class="setting-multi-radio">
<thead>
<tr>
<th>{{ value.title }}</th>
{% for item in setting.children %}
{% capture item_name %}{{ item[0] }}{% endcapture %}
<th>{{ value.children[item_name] }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for option in setting.options %}
<tr>
<th>{{ value.options[option] }}</th>
{% for item in setting.children %}
<td><input class="setting-item"{% if item[1].default == option %} checked{% endif %} type="radio" name="{{ name }}.{{ item[0] }}" value="{{ option }}"></td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
{% endfor %}
{% endfor %}

<script>
settings.onChange("{{ name }}", function (newValue, oldValue) {
var list = document.getElementsByName("{{ name }}");
for (var i = 0; i < list.length; i++) {
list[i].checked = list[i].value === newValue;
list[i].onchange = function () {
if (this.checked) {
settings.set(this.name, this.value);
}
}
}
});
for (const settingItem of document.getElementsByClassName("setting-item")) {
settingItem.addEventListener("change", ({ target }) => settings.set(target.name, target.value));
settings.onChange(settingItem.name, (value) => settingItem.type === "radio" && (settingItem.checked = settingItem.value === value));
}
</script>
{% endif %}
{% endfor %}
{% endcapture %}
{{ notice | markdownify }}
{% endfor %}

<style>.notice label input { display: inline }</style>
14 changes: 10 additions & 4 deletions _sass/minimal-mistakes-plus.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ blockquote {
word-break: break-word;
}

.task-list-item label {
display: inline
.preview {
top: 0;
z-index: 999;
padding: 0.4em;
position: sticky;
margin: 0 !important;
}

.m0 {
margin: 0 !important;
table.setting-multi-radio td {
border: 0;
text-align: center;
border-left: 1px solid mix(#000, $border-color, 25%);
}
40 changes: 40 additions & 0 deletions assets/js/meta.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(() => {
const pageTitle = document.getElementById("page-title");
if (pageTitle === null) return;
const header = pageTitle.parentElement;
let metas = header.getElementsByClassName("page__meta")[0];
if (metas === null) {
metas = document.createElement("div");
element.className = "page__meta";
header.append(element);
}
window.appendMeta = (text, icon) => {
if (metas.children.length > 0) {
const sep = document.createElement("span");
sep.className = "page__meta-sep";
metas.append(sep);
}
const meta = document.createElement("span");
if (icon !== undefined) {
const metaIcon = document.createElement("i");
metaIcon.className = icon;
meta.append(metaIcon, " ");
}
meta.append(text.trim());
metas.append(meta);
};
window.hits = (tag) => {
if (settings.get("miscellaneous_hits") === "disable") return;
const hitsUrl = new URL("https://hits.zkitefly.eu.org");
hitsUrl.searchParams.set("tag", tag);
fetch(hitsUrl, { method: "HEAD" }).then((response) => {
if (response.status !== 200) return;
const { headers } = response;
const total = headers.get("X-Total-Hits");
const today = headers.get("X-Today-Hits");
if (total !== null && today !== null) {
appendMeta(today + " / " + total, "far fa-eye");
}
});
};
})();
96 changes: 28 additions & 68 deletions assets/js/settings.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,36 @@
---
layout: null
---
(function (global) {
var PREFIX = "HMCL_DOCS_SETTINGS_";
var data = {};
var events = {};
var config = /*{%comment%}*/{}/*{%endcomment%}*//**{{'/'}}{{ site.data.settings | jsonify }}/**/;

global.addEventListener("storage", function (event) {
if (!event.key) return;
if (event.key.indexOf(PREFIX) !== 0) return;

var handlers = events[event.key];
if (!handlers) return;

var newValue = event.newValue;
var oldValue = event.oldValue;
if (oldValue === newValue) return;

data[event.key] = newValue;
for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue, oldValue);
}
(function () {
const PREFIX = "HMCL_DOCS_SETTINGS_", data = {}, bus = new EventTarget(), configs = /*{%comment%}*/{}/*{%endcomment%}*/ /**{{'/'}}{{ site.data.settings | jsonify }}/**/;
window.addEventListener("storage", ({ key, newValue }) => key !== null && key.startsWith(PREFIX) && newValue !== data[key] && bus.dispatchEvent(new CustomEvent(key, { detail: (data[key] = newValue) })));
for (const [key, config] of Object.entries(configs)) {
if (config.children === undefined) continue;
for (const [childKey, child] of Object.entries(config.children)) {
configs[`${key}.${childKey}`] = { ...config, ...child };
}
});

var settings = {
set: function (key, value) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
var newValue = value + "";
data[strKey] = newValue;
localStorage.setItem(strKey, newValue);
var handlers = events[strKey];
if (!handlers) return;

for (var i = 0; i < handlers.length; i++) {
if (typeof handlers[i] === "function") {
handlers[i](newValue);
}
}
}
const formatKey = (key) => PREFIX + key.toUpperCase().replaceAll(".", "_");
window.settings = {
set(key, value) {
const name = formatKey(key);
localStorage.setItem(name, (data[name] = String(value)));
bus.dispatchEvent(new CustomEvent(name, { detail: data[name] }));
},

get: function (key, defaultValue) {
if (config[key] === undefined) return;
var strKey = (PREFIX + key).toUpperCase();
data.hasOwnProperty(strKey) || (data[strKey] = localStorage.getItem(strKey));
if (typeof defaultValue === "string" && data[strKey] === null) {
return defaultValue;
}
return data[strKey];
get(key) {
const name = formatKey(key);
if (data[name] !== undefined) return data[name];
const value = localStorage.getItem(name);
if (value !== null) return data[name] = value;
const config = configs[key];
if (config === undefined || typeof config.default !== "string") return null;
return config.default;
},

refresh: function (key) {
if (config[key] === undefined) return;
settings.set(key, settings.get(key, config[key].default));
onChange(key, handler) {
const value = this.get(key);
if (value === null) return;
handler(value);
bus.addEventListener(formatKey(key), (event) => handler(event.detail));
},

onChange: function (key, handler) {
if (config[key] === undefined) return;
if (typeof handler !== "function") return;
var strKey = (PREFIX + key).toUpperCase();
if (config[key].type === "radio") {
handler(settings.get(key, config[key].default));
}
if (!events[strKey]) {
events[strKey] = [handler];
} else {
events[strKey].push(handler);
}
}
};
global.settings = settings;
})(window);
})();
20 changes: 14 additions & 6 deletions assets/js/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ layout: null
window.addEventListener("DOMContentLoaded", function () {
var skinLink = document.getElementById("skin");
var darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
function applySkin(skin) {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + skin + ".css";
}
function applyDarkSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_dark", "dark") + ".css";
applySkin(settings.get("appearance_skin.dark"));
}
function applyLightSkin() {
skinLink.href = "{{ '/assets/css/skins/' | relative_url }}" + settings.get("appearance_skin_light", "default") + ".css";
applySkin(settings.get("appearance_skin.light"));
}
function autoSchemeHandler() {
if (darkModeQuery.matches) {
Expand Down Expand Up @@ -61,10 +64,15 @@ window.addEventListener("DOMContentLoaded", function () {
}
}
settings.onChange("appearance_color", applyTheme);
settings.onChange("appearance_skin_dark", function () {
settings.refresh("appearance_color");
settings.onChange("appearance_skin.dark", function () {
applyTheme(settings.get("appearance_color"));
});
settings.onChange("appearance_skin.light", function () {
applyTheme(settings.get("appearance_color"));
});
settings.onChange("appearance_skin_light", function () {
settings.refresh("appearance_color");
settings.onChange("appearance_color_switcher", function (value) {
if (modeSwitcher !== null) {
modeSwitcher.style.display = value === "enable" ? "" : "none";
}
});
});
Loading