Compare commits

...

3 Commits

Author SHA1 Message Date
63f0ca5b9f Merge branch 'main' of https://gitea.uptoz.cn/UPToZ/halo-theme-hao 2024-04-12 15:14:48 +08:00
b8eeb5a816 1.增加了许可证书
2.增加了README文档
2024-04-12 15:14:34 +08:00
f29a5788dd 初始化仓库代码 2024-04-12 14:35:37 +08:00
272 changed files with 57427 additions and 0 deletions

175
annotation-setting.yaml Normal file
View File

@ -0,0 +1,175 @@
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: content.halo.run
kind: Post
formSchema:
- $formkit: "radio"
name: "ai"
label: "AI 摘要"
help: "默认后台设置"
options:
- label: "启用"
value: "true"
- label: "禁用"
value: "false"
- $formkit: "radio"
name: "copyrightEnable"
id: "copyrightEnable"
key: "copyrightEnable"
label: "显示版权声明"
help: "默认后台设置"
options:
- label: "显示"
value: "true"
- label: "隐藏"
value: "false"
- $formkit: "radio"
name: "copyrightType"
label: "版权声明类型"
value: "original"
if: "$get(copyrightEnable).value != 'false'"
options:
- label: "原创"
value: "original"
- label: "转载"
value: "reprint"
- $formkit: "text"
name: "copyrightUrl"
label: "版权声明链接"
help: "默认后台设置"
if: "$get(copyrightEnable).value != 'false'"
placeholder: "请输入链接"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: ""
kind: MenuItem
formSchema:
- $formkit: "text"
name: "icon"
label: "图标"
- $formkit: "radio"
name: "isVertical"
value: "0"
label: "该菜单的子菜单是否为垂直菜单"
options:
- label: "是"
value: "1"
- label: "否"
value: "0"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: core.halo.run
kind: LinkGroup
formSchema:
- $formkit: "radio"
name: "displayStyle"
label: "分组方式"
value: "default"
options:
- label: "默认"
value: "default"
- label: "美化"
value: "beautify"
- label: "失联"
value: "deprecated"
- $formkit: "textarea"
name: "description"
label: "描述"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: core.halo.run
kind: Link
formSchema:
- $formkit: "attachment"
name: "siteshot"
label: "背景"
- $formkit: "text"
name: "label"
label: "标签"
- $formkit: "color"
name: "labelColor"
value: "#425AEF"
label: "标签颜色"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: core.halo.run
kind: PhotoGroup
formSchema:
- $formkit: "attachment"
name: "cover"
label: "分组图片"
- $formkit: "attachment"
name: "background"
label: "分组顶部 banner 图片"
- $formkit: "textarea"
name: "description"
label: "分组描述"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: core.halo.run
kind: EquipmentGroup
formSchema:
- $formkit: "textarea"
name: "description"
label: "分组描述"
---
apiVersion: v1alpha1
kind: AnnotationSetting
metadata:
generateName: annotation-setting-
spec:
targetRef:
group: core.halo.run
kind: Equipment
formSchema:
- $formkit: "text"
name: "model"
label: "装备型号/版本"
- $formkit: "text"
name: "button"
label: "左下角按钮显示文字"
value: "详情"
- $formkit: "text"
name: "link"
label: "左下角按钮跳转链接"

3325
settings.yaml Normal file

File diff suppressed because it is too large Load Diff

BIN
templates/.DS_Store vendored Normal file

Binary file not shown.

93
templates/about.html Normal file
View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:replace="~{modules/layouts/layout :: layout(content = ~{::content}, htmlType = 'about',title = ${singlePage.spec.title + ' | ' + site.title}, head = ~{::head})}">
<th:block th:fragment="head">
<th:block th:replace="~{modules/common/open-graph :: open-graph(_title = ${singlePage.spec.title},
_permalink = ${singlePage.status.permalink},
_cover = ${singlePage.spec.cover},
_excerpt = ${singlePage.status.excerpt},
_type = 'website')}"></th:block>
</th:block>
<th:block th:fragment="content">
<div class="page" id="body-wrap">
<!-- 头部导航栏 -->
<header class="not-top-img" id="page-header">
<nav th:replace="~{modules/nav :: nav(title = ${singlePage.spec.title})}"></nav>
</header>
<main class="layout hide-aside" id="content-inner">
<div id="page">
<div id="about-page">
<div class="author-info">
<div class="author-tag-left"
th:if="${not #lists.isEmpty(theme.config.about.authorInfoLeftTags)}"
th:with="authorTags = ${theme.config.about.authorInfoLeftTags}">
<span class="author-tag" th:each="authorTag : ${authorTags}"
th:text="${authorTag.tag}"></span>
</div>
<div class="author-img">
<img
th:src="@{${#strings.isEmpty(site.logo) ? assets_link + '/images/hao-logo.jpg' : site.logo}}">
</div>
<div class="author-tag-right"
th:if="${not #lists.isEmpty(theme.config.about.authorInfoRightTags)}"
th:with="authorTags = ${theme.config.about.authorInfoRightTags}">
<span class="author-tag" th:each="authorTag : ${authorTags}"
th:text="${authorTag.tag}"></span>
</div>
</div>
<div class="author-title" th:text="${singlePage.spec.title}"></div>
<th:block
th:replace="~{modules/about-widgets :: about-widgets(${theme.config.about.widgetList})}"></th:block>
<div class="author-content">
<div class="create-site-post author-content-item single" th:utext="${theme.config.about.xjlc}">
</div>
</div>
<th:block th:replace="~{modules/widgets/about-widgets/tenyear}"></th:block>
<th:block th:replace="~{modules/widgets/about-widgets/about-reward}"></th:block>
</div>
<th:block th:if="${theme.config.about.tenyear.tenyear_enable}">
<link rel="stylesheet" th:href="${assets_link + '/css/tenyear.css' + theme_version}" media="all"
onload="this.media='all'">
<script> (() => {
let t = document.querySelector(".progress"),
n = document.querySelector(".past-time"),
o = document.querySelector(".percentage-label"),
r = document.querySelector(".start-time"),
s = document.querySelector(".end-time"),
a = new Date("[(${theme.config.about.tenyear.start_time})]").getTime(),
i = new Date("[(${theme.config.about.tenyear.end_time})]").getTime(),
c = ((new Date).getTime() - a) / (i - a) * 100,
u = c <= 100 ? c + "%" : "100%",
m = c <= 100 ? c.toFixed(0) + "%" : "已达标 ";
if (c < 10){
m = "";
}
n.style.setProperty("--past-time-percentage", c + "%"), t.style.setProperty("--progress-percentage", u), o.textContent = m, o.style.left = `calc(${c}% - 3rem)`, r.textContent = "" + new Date(a).toLocaleDateString(), s.textContent = "" + new Date(i).toLocaleDateString(), setTimeout(() => {
o.style.visibility = "visible"
}, 2500);
})()
</script>
</th:block>
</div>
</main>
<!-- 底部 -->
<footer th:replace="~{modules/footer}"/>
</div>
</th:block>
</html>

193
templates/album.html Normal file
View File

@ -0,0 +1,193 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:replace="~{modules/layouts/layout :: layout(content = ~{::content}, htmlType = 'page',title = ${singlePage.spec.title + ' | ' + site.title}, head = ~{::head})}">
<th:block th:fragment="head">
<th:block th:replace="~{modules/common/open-graph :: open-graph(_title = ${singlePage.spec.title},
_permalink = ${singlePage.status.permalink},
_cover = ${singlePage.spec.cover},
_excerpt = ${singlePage.status.excerpt},
_type = 'website')}"></th:block>
</th:block>
<th:block th:fragment="content">
<div class="page" id="body-wrap">
<!-- 头部导航栏 -->
<header class="not-top-img" id="page-header">
<nav th:replace="~{modules/nav :: nav(title = ${singlePage.spec.title})}"></nav>
</header>
<main class="layout hide-aside" id="content-inner">
<div id="page">
<div id="album" th:if="${#strings.equals(theme.config.photos.photosStyle, 'default')}">
<div th:replace="~{macro/author-content :: author-content(background = ${singlePage.spec.cover},
smallTitle = '相册集',
bigTitle = ${singlePage.spec.title},
detail = ${singlePage.spec.excerpt.raw},
buttonUrl = '',
buttonTitle = '')}"></div>
<div class="card-album">
<th:block th:each="group : ${photoFinder.groupBy()}">
<div class="card" th:onclick="pjax.loadUrl([['/photos?group='+${group.metadata.name}]])">
<img class="card_cover"
th:src="${isLazyload ? loadingImg : #annotations.get(group, 'cover')}"
th:data-lazy-src="${ isLazyload ? #annotations.get(group, 'cover') : ''}"
>
<div class="card__content">
<p class="card__category" th:text="${group.spec.displayName}"></p>
<h3 class="card__heading" th:text="${#annotations.get(group, 'description')}"></h3>
</div>
</div>
</th:block>
<th:block th:each="photos : ${photoFinder.groupBy()}">
<div class="album-content-nocover"></div>
</th:block>
</div>
</div>
<div class="gallery-groups" th:if="${#strings.equals(theme.config.photos.photosStyle, 'one')}">
<h2 style="text-align:center;">[[${theme.config.photos.bigTitle}]]</h2>
<div class="gallery-group-main">
<th:block th:each="group : ${photoFinder.groupBy()}">
<figure class="gallery-group no-lightbox">
<img class="gallery-group-img no-lightbox"
th:src="${isLazyload ? loadingImg : #annotations.get(group, 'cover')}"
th:data-lazy-src="${ isLazyload ? #annotations.get(group, 'cover') : ''}"
alt="Group Image Gallery">
<figcaption>
<div class="gallery-group-name">[[${group.spec.displayName}]]</div>
<p>[[${#annotations.get(group, 'description')}]]</p><a target="_blank"
rel="noopener" th:onclick="pjax.loadUrl([['/photos?group='+${group.metadata.name}]])"></a>
</figcaption>
</figure>
</th:block>
</div>
</div>
<style>
.gallery-groups {
box-shadow: var(--heo-shadow-border);
padding: 1rem 2rem;
border-radius: 12px;
background: var(--heo-card-bg);
border: var(--style-border);
width: 100%;
align-self: flex-start;
animation: slide-in 0.6s 0.1s backwards;
}
:root {
--album-background-dark: #2d3548;
--album-text-light: rgba(255, 255, 255, 0.6);
--album-text-lighter: rgba(255, 255, 255, 0.9);
--album-spacing-s: 8px;
--album-spacing-m: 16px;
--album-spacing-l: 24px;
--album-spacing-xl: 32px;
--album-spacing-xxl: 64px
}
#album .card-album {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin: var(--album-spacing-xxl) 0 0
}
#album .card-album .album-content-nocover {
width: calc(100% / 4 - 40px)
}
#album .card-album .card {
list-style: none;
position: relative;
display: flex;
width: calc(100% / 4 - 10px);
padding: 10px
}
#album .card-album .card:hover {
cursor: pointer
}
#album .card_cover {
border-radius: var(--album-spacing-l);
filter: brightness(.75) saturate(1.2) contrast(.85);
transform-origin: center;
transform: scale(1) translateZ(0);
transition: filter .2s linear, transform .2s linear;
max-width: 100%;
overflow: hidden;
height: 550px;
width: 100%;
max-width: 100%;
object-fit: cover;
border-radius: var(--album-spacing-l)
}
#album .card:hover .card_cover {
transform: scale(1.05) translateZ(0);
filter: brightness(.9) saturate(1.2) contrast(1)
}
#album .card-album:hover>.card:not(:hover) .card_cover {
filter: brightness(.5) saturate(.9) contrast(1.2) blur(20px)
}
#album .card__content {
left: 0;
padding: var(--album-spacing-l);
position: absolute;
top: 0
}
#album .card__category {
color: var(--album-text-light);
font-size: .8rem;
margin-bottom: var(--album-spacing-s);
text-transform: uppercase
}
#album .card__heading {
color: var(--album-text-lighter);
font-size: 1.5rem;
text-shadow: 2px 2px 20px rgba(0, 0, 0, .2);
line-height: 1.4;
word-spacing: 100vw
}
@media (min-width: 1024px) {
#album img.card_cover {
height: 600px
}
}
@media (max-width: 960px) {
#album .card-album .card {
width: calc(100% / 2 - 40px)
}
}
@media (max-width: 540px) {
#album .card-album .card {
width: calc(100%)
}
}
</style>
<!--/* 评论组件 */-->
<th:block th:replace="~{modules/comment :: comment(group = 'content.halo.run',
kind = 'SinglePage',
name = ${singlePage.metadata.name},
allowComment = ${singlePage.spec.allowComment})}" />
</div>
</main>
<!-- 底部 -->
<footer th:replace="~{modules/footer}"/>
<!-- 卡片顶部气泡效果 -->
<script th:if="${theme.config.other.bubbleEnable}" async data-pjax
th:src="${assets_link + '/libs/canvas/bubble.js'}"></script>
</div>
</th:block>
</html>

67
templates/archives.html Normal file
View File

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:replace="~{modules/layouts/layout :: layout(content = ~{::content}, htmlType = 'archive',title = ${'文章归档' + ' | ' + site.title}, head = ~{::head})}">
<th:block th:fragment="head">
<th:block th:replace="~{modules/common/open-graph :: open-graph(_title = '文章归档',
_permalink = '/archives',
_cover = ${theme.config.other.opengraph.image},
_excerpt = ${site.seo.description},
_type = 'website')}"></th:block>
</th:block>
<th:block th:fragment="content">
<div class="page" id="body-wrap">
<header class="not-top-img" id="page-header">
<nav th:replace="~{modules/nav :: nav(title = '文章归档')}"></nav>
</header>
<main class="layout" id="content-inner">
<!-- archive -->
<div id="archive">
<div class="article-sort-title">文章<sup>[[${siteStatsFinder.getStats().post}]]</sup></div>
<div class="article-sort" th:each="archive : ${archives.items}"
th:with='postRandomImg=${#strings.contains(theme.config.layout.postRandomImg,"?") ? theme.config.layout.postRandomImg+"&" : theme.config.layout.postRandomImg+"?"}'>
<div class="article-sort-item year" th:text="${archive.year}"></div>
<div class="article-sort" th:each="month : ${archive.months}">
<!-- 月份没有样式所以不显示 -->
<!-- <div class="article-sort-item" th:text="${month.month}"></div> -->
<div class="article-sort-item" th:each="post : ${month.posts}">
<a class="article-sort-item-img" th:href="@{${post.status.permalink}}"
th:title="${post.spec.title}">
<img th:alt="${post.spec.title}"
th:src="${#strings.isEmpty(post.spec.cover) ? postRandomImg+post.spec.title : post.spec.cover}">
</a>
<div class="article-sort-item-info">
<div class="article-sort-item-time"><i class="far fa-calendar-alt"></i>
<time class="post-meta-date-created"
th:attr="datetime=${#dates.format(post.spec.publishTime,'yyyy-MM-dd HH:mm:ss')}"
th:text="${#dates.format(post.spec.publishTime,'yyyy-MM-dd')}"
th:title="'创建于' + ${#dates.format(post.spec.publishTime,'yyyy-MM-dd HH:mm:ss')}">
</time>
</div>
<a class="article-sort-item-title" onclick="window.event.cancelBubble=!0"
th:href="@{${post.status.permalink}}" th:text="${post.spec.title}"
th:title="${post.spec.title}"></a>
<div class="article-sort-item-tags">
<a class="article-meta__tags"
th:each="tag : ${post.tags}" th:href="@{${tag.status.permalink}}">
<span class="tags-punctuation">[[${tag.spec.displayName}]]</span>
</a>
<span class="article-meta__link"></span>
</div>
</div>
</div>
</div>
</div>
<!-- 分页 -->
<div th:replace="~{modules/widgets/page :: page('/archives',${archives},false,'')}"></div>
</div>
<!-- sidebar -->
<div th:replace="~{modules/aside :: aside(${theme.config.sidebar.widgetss.categoryWidgets})}"></div>
</main>
<!-- 底部 -->
<footer th:replace="~{modules/footer}"/>
</div>
</th:block>
</html>

BIN
templates/assets/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,145 @@
:root {
--light-grey: rgba(255, 255, 255, 0.7);
--white: rgba(255, 255, 255, 0.9);
}
@media screen and (max-width: 768px) {
#page-header #nav {
background: 0%;
transition: 0s;
}
}
.page .back-home-button {
color: rgba(255, 255, 255, 0.7);
}
.page #nav #site-name span {
color: var(--light-grey);
}
.nav-fixed #nav #site-name span{
color: var(--heo-fontcolor);
}
#nav .site-page {
color: rgba(255, 255, 255, 0.7);
}
#page-header.full_page {
height: 100vh;
background-attachment: fixed;
border-radius: 0;
}
#page-header.full_page #site-info {
position: absolute;
top: 43%;
padding: 0 10px;
width: 100%;
}
#page-header #scroll-down {
position: absolute;
bottom: 0;
width: 100%;
cursor: pointer;
z-index: 1;
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
-webkit-box-align: center;
-moz-box-align: center;
-o-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
-webkit-box-pack: center;
-moz-box-pack: center;
-o-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
#page-header #scroll-down .scroll-down-effects {
position: relative;
width: 100%;
color: var(--light-grey);
font-size: 30px;
}
/* 首页头图加载 */
.pl-container {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
will-change: transform;
/* 添加性能优化 */
animation: blur-to-clear 2s cubic-bezier(.62, .21, .25, 1) 0s 1 normal backwards running, scale 1.5s cubic-bezier(.62, .21, .25, 1) 0s 1 both;
}
.pl-img {
width: 100%;
height: 100%;
position: absolute;
background-position: center;
background-size: cover;
background-repeat: no-repeat;
opacity: 0;
transition: opacity 1s;
}
@keyframes blur-to-clear {
0% {
filter: blur(50px);
opacity: 1;
}
100% {
filter: blur(0);
opacity: 1;
}
}
@keyframes scale {
0% {
transform: scale(1.5) translateZ(0);
opacity: 0;
}
to {
transform: scale(1) translateZ(0);
opacity: 1;
}
}
.pl-visible {
opacity: 1;
}
/* 为首页图片加上遮罩 */
.video {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: 0;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAKUlEQVQImU3IMREAIAgAwJfNkQCEsH8cijjpMf6vnXlQaIiJFx+omEBfmqIEZLe2jzcAAAAASUVORK5CYII=);
}
.pl-blur {
/* 小图锯齿多,增加高斯模糊 */
filter: blur(50px);
}
#nav a {
color: var(--light-grey);
}

View File

@ -0,0 +1,316 @@
#post .post-copyright {
background: var(--heo-secondbg);
border-width: 1px;
transition: 0.3s;
position: relative;
margin: 80px 0px 30px;
border-radius: 12px;
padding: 34px 0 20px 0;
border: var(--style-border-always);
}
@media screen and (max-width: 768px) {
#post .post-copyright {
padding: 1rem 1.3rem;
}
}
.post-tools {
display: flex;
width: 100%;
justify-content: center;
margin-top: 8px;
flex-wrap: wrap;
-webkit-user-select: none;
}
.post-copyright__author_img {
width: 66px;
height: 66px;
margin: auto;
border-radius: 66px;
overflow: hidden;
position: absolute;
left: calc(50% - 33px);
top: -33px;
border: var(--style-border-always);
box-shadow: var(--heo-shadow-main);
}
.post-copyright__author_img img {
position: absolute;
bottom: 0;
left: 0;
}
img.post-copyright__author_img_back {
border-radius: 66px;
z-index: 10;
}
img.post-copyright__author_img_front {
z-index: 20;
transform: scale(1.2) translateY(6px);
}
.post-copyright__author_img:hover img.post-copyright__author_img_front {
transform: scale(1) translateY(3px);
}
.post-copyright__author_img:hover img.post-copyright__author_img_back {
transform: scale(0.8);
}
.post-copyright__author_name {
text-align: center;
font-size: 20px;
font-weight: bold;
margin-top: 16px;
color: var(--heo-fontcolor);
line-height: 1;
}
.post-copyright__author_desc {
text-align: center;
font-size: 14px;
color: var(--heo-secondtext);
margin-top: 4px;
}
.post-copyright__author {
display: flex;
align-items: center;
}
/* 提示 */
#post>div.post-copyright>div.post-copyright__notice {
font-size: 12px;
margin: 0.5rem 0;
}
#post .post-copyright .post-copyright-info {
padding-left: 0;
color: var(--heo-secondtext);
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
text-align: center;
}
/* 作者名 */
#post .post-copyright .post-copyright-info a {
padding: 0;
color: var(--heo-fontcolor);
font-weight: bold;
}
.post-reward {
margin-top: 0rem;
display: flex;
justify-content: center;
}
/* 打赏作者按钮 */
.post-reward .reward-button {
background: var(--heo-red);
color: var(--heo-white);
padding: 0 16px;
height: 40px;
line-height: 39px;
box-shadow: var(--heo-shadow-red);
display: inline-block;
cursor: pointer;
transition: all 0.4s ease 0s;
}
.post-reward:hover .reward-button {
color: var(--heo-white);
background: var(--heo-theme);
box-shadow: none;
}
.reward-link.mode {
background: var(--heo-green);
color: var(--heo-white);
padding: 0 16px;
height: 40px;
line-height: 39px;
box-shadow: var(--heo-shadow-green);
border-radius: 8px;
margin-left: 0.5rem;
text-align: center;
transition: 0.3s;
}
.reward-link.mode a {
color: var(--heo-white);
}
.reward-link.mode i {
margin-right: 4px;
}
.reward-link.mode:hover {
background: var(--heo-theme);
box-shadow: none;
}
/* 捐助工具栏 */
.post-tools-left {
white-space: nowrap;
display: flex;
text-overflow: ellipsis;
flex-wrap: wrap;
}
.post-tools-right {
padding-right: 0px;
display: flex;
align-items: center;
flex-direction: row;
flex-wrap: wrap;
}
@media screen and (max-width: 768px) {
.post-tools-left>div {
margin: 8px;
}
.post-tools-left {
white-space: nowrap;
display: flex;
text-overflow: ellipsis;
justify-content: center;
width: 100%;
}
.post-tools-right {
margin-top: 1rem;
width: 100%;
justify-content: center;
}
}
#post .post-copyright .post-copyright-info a:hover {
text-decoration: none;
background-color: var(--heo-main);
color: var(--heo-white);
cursor: pointer;
border-radius: 4px;
}
#post .tag_share .post-meta__tag-list {
display: flex;
padding: 0;
width: 100%;
flex-wrap: wrap;
flex-direction: row;
}
#post .tag_share .post-meta__tag-list a {
margin-bottom: 8px;
margin-right: 8px;
}
/* 文章标签 */
#post .tag_share .post-meta__tags {
background: var(--heo-card-bg);
border: var(--style-border-always);
color: var(--heo-fontcolor);
border-radius: 8px;
margin: 0;
display: flex;
align-items: center;
white-space: nowrap;
height: 40px;
padding: 0px 0.6rem;
width: fit-content;
font-size: 0.85em;
transition: all 0.2s ease-in-out 0s;
}
#post .tag_share .post-meta__tags:hover {
background: var(--heo-lighttext);
box-shadow: var(--heo-shadow-main);
color: var(--heo-white);
}
@media screen and (min-width: 1300px) {
#post .tag_share .post-meta__tags {
background: var(--heo-card-bg);
border: var(--style-border);
}
#post .tag_share .post-meta__tags:hover {
border: var(--style-border-hover);
}
}
@media screen and (max-width: 768px) {
#post .post-copyright {
background: var(--heo-card-bg);
box-shadow: var(--heo-shadow-border);
}
.post-copyright .post-meta-original {
display: none;
}
.post-copyright__original {
display: none;
}
}
@media screen and (max-width: 768px) {
#post>div.post-copyright>div.post-copyright__author>span>span {
-webkit-line-clamp: 3;
}
#post .post-copyright .post-copyright-info {
-webkit-line-clamp: 2;
}
#post .post-copyright .post-copyright-title {
-webkit-line-clamp: 3;
line-height: 1.2;
}
}
.post-reward .reward-main {
left: -96px;
width: fit-content;
}
@media screen and (max-width: 768px) {
.post-reward .reward-main {
justify-content: center !important;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 102;
width: 100%;
margin: auto;
padding: 0;
}
}
.post-reward .reward-main .reward-all {
background:var(--heo-card-bg);
}
.post-tools .post-tools-left .rewardLeftButton,.post-tools .post-tools-left .shareRight {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
margin: 10px
}

View File

@ -0,0 +1,214 @@
/* 版权信息 */
/* 背景 */
#post .post-copyright {
background: var(--heo-card-bg);
padding: 1rem 1.3rem;
overflow: hidden;
border: var(--style-border);
border-width: 1px;
transition: 0.3s;
position: relative;
margin: 1.8rem 0px 0.5rem;
border-radius: 12px;
}
#post .post-copyright:after {
position: absolute;
right: 22px;
top: -77px;
content: "\e668";
font-family: "haofont" !important;
font-size: 180px;
font-family: "Font Awesome 5 Brands";
color: var(--heo-fontcolor);
opacity: 0.1;
/*filter: blur(7px);*/
}
@media screen and (max-width: 768px) {
#post .post-copyright {
padding: 1rem 1.3rem;
}
}
.post-tools {
display: flex;
width: 100%;
justify-content: space-between;
margin-top: 2rem;
flex-wrap: wrap;
}
/* 捐助工具栏 */
.post-tools-left {
white-space: nowrap;
display: flex;
text-overflow: ellipsis;
flex-wrap: wrap;
margin-bottom: 0.5rem;
}
.post-tools-right {
overflow: scroll;
overflow-x: overlay;
padding-right: 0px;
display: flex;
align-items: center;
margin-bottom: 0.5rem;
}
@media screen and (max-width: 768px) {
.post-tools-left > div {
margin: 8px;
}
.post-tools-left {
white-space: nowrap;
display: flex;
text-overflow: ellipsis;
margin-top: 1rem;
justify-content: center;
width: 100%;
}
.post-tools-right {
margin-top: 1rem;
width: 100%;
justify-content: center;
}
}
.reward-link.mode {
background: var(--heo-green);
color: var(--heo-white);
padding: 0;
width: 173px;
height: 40px;
line-height: 39px;
box-shadow: var(--heo-shadow-green);
border-radius: 8px;
margin-left: 0.5rem;
text-align: center;
transition: 0.3s;
}
@media screen and (min-width: 1300px) {
.reward-link.mode:hover {
transform: scale(1.03);
}
.reward-link.mode:active {
transform: scale(0.97);
}
}
.reward-link.mode a {
color: var(--heo-white);
}
.reward-link.mode i {
margin-right: 4px;
}
.reward-link.mode:hover {
background: var(--heo-theme);
box-shadow: none;
}
.post-reward .reward-button {
display: inline-block;
padding: 0.2rem 1.2rem;
background: var(--btn-bg);
color: var(--btn-color);
cursor: pointer;
transition: all 0.4s ease 0s;
border-radius: 5px;
}
/* 赞赏作者按钮 */
.post-reward .reward-button {
background: var(--heo-red);
color: var(--heo-white);
padding: 0;
width: 133px;
height: 40px;
line-height: 39px;
box-shadow: var(--heo-shadow-red);
}
#post .post-copyright .post-copyright-info a:hover {
text-decoration: none;
background-color: rgb(255, 255, 255);
color: rgb(59, 130, 255);
cursor: pointer;
border-radius: 4px;
}
/* 标签列表页 */
#post .tag_share .post-meta__tag-list {
display: flex;
}
@media screen and (max-width: 768px) {
#post .tag_share .post-meta__tag-list {
display: flex;
overflow: scroll;
position: absolute;
left: 0;
padding: 0 20px 0 20px;
width: 100%;
}
}
#post .tag_share .post-meta__tags:not(:last-child) {
margin: 0 0.5rem 0 0;
}
/* 提示 */
#post > div.post-copyright > div.post-copyright__notice {
font-size: 0.7rem;
line-height: 1rem;
margin: 0.5rem 0;
}
/* 作者名 */
#post .post-copyright .post-copyright-info a {
padding: 0;
color: var(--heo-fontcolor);
font-weight: bold;
}
#post .post-copyright .post-copyright-info a:hover {
color: var(--heo-lighttext);
}
#post .post-copyright .post-copyright-info {
padding-left: 0;
color: var(--heo-fontcolor);
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
@media screen and (max-width: 768px) {
.post-reward .reward-main {
justify-content: center !important;
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 102;
width: 100%;
margin: auto;
padding: 0;
}
}
.post-reward .reward-main .reward-all {
background:var(--heo-card-bg);
}

View File

@ -0,0 +1,218 @@
.read-mode {
--font-color: #4c4948;
--readmode-light-color: #fff;
--white: #4c4948;
--light-grey: #4c4948;
--gray: #d6dbdf;
--hr-border: #d6dbdf;
--hr-before-color: #b9c2c9;
--highlight-bg: #f7f7f7;
--exit-btn-bg: #c0c0c0;
--exit-btn-color: #fff;
--exit-btn-hover: #8d8d8d;
--pseudo-hover: none
}
[data-theme=dark] .read-mode {
--font-color: rgba(255,255,255,0.7);
--readmode-light-color: #0d0d0d;
--white: rgba(255,255,255,0.9);
--light-grey: rgba(255,255,255,0.7);
--gray: rgba(255,255,255,0.7);
--hr-border: rgba(255,255,255,0.5);
--hr-before-color: rgba(255,255,255,0.7);
--highlight-bg: #171717;
--exit-btn-bg: #1f1f1f;
--exit-btn-color: rgba(255,255,255,0.9);
--exit-btn-hover: #525252
}
.read-mode {
background: var(--readmode-light-color)
}
.read-mode .exit-readmode {
position: fixed;
top: 30px;
right: 30px;
z-index: 100;
width: 40px;
height: 40px;
border-radius: 8px;
background: var(--exit-btn-bg);
color: var(--exit-btn-color);
font-size: 16px;
-webkit-transition: background .3s;
-moz-transition: background .3s;
-o-transition: background .3s;
-ms-transition: background .3s;
transition: background .3s
}
@media screen and (max-width: 768px) {
.read-mode .exit-readmode {
top:initial;
bottom: 30px
}
}
.read-mode .exit-readmode:hover {
background: var(--exit-btn-hover)
}
.read-mode #aside-content {
display: none
}
.read-mode #page-header.post-bg {
background-color: transparent;
background-image: none!important
}
.read-mode #page-header.post-bg:before {
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0)
}
.read-mode #page-header.post-bg>#post-info {
text-align: center
}
.read-mode #post {
margin: 0 auto;
background: 0 0;
-webkit-box-shadow: none;
box-shadow: none
}
.read-mode #post:hover {
-webkit-box-shadow: none;
box-shadow: none
}
.read-mode>canvas {
display: none!important
}
.read-mode #footer,.read-mode #nav,.read-mode #post>:not(#post-info):not(.post-content),.read-mode #rightside,.read-mode #web_bg,.read-mode .highlight-tools,.read-mode .not-top-img,.read-mode .post-outdate-notice {
display: none!important
}
.read-mode #article-container a {
color: #99a9bf
}
.read-mode #article-container .highlight:not(.js-file-line-container),.read-mode #article-container pre {
background: var(--highlight-bg)!important
}
.read-mode #article-container .highlight:not(.js-file-line-container) *,.read-mode #article-container pre * {
color: var(--font-color)!important
}
.read-mode #article-container figure.highlight {
border-radius: 0!important;
-webkit-box-shadow: none!important;
box-shadow: none!important
}
.read-mode #article-container figure.highlight>:not(.highlight-tools) {
display: block!important
}
.read-mode #article-container figure.highlight .line:before {
color: var(--font-color)!important
}
.read-mode #article-container figure.highlight .hljs {
background: var(-highlight-bg)!important
}
.read-mode #article-container h1,.read-mode #article-container h2,.read-mode #article-container h3,.read-mode #article-container h4,.read-mode #article-container h5,.read-mode #article-container h6 {
padding: 0
}
.read-mode #article-container h1:before,.read-mode #article-container h2:before,.read-mode #article-container h3:before,.read-mode #article-container h4:before,.read-mode #article-container h5:before,.read-mode #article-container h6:before {
content: ''
}
.read-mode #article-container h1:hover,.read-mode #article-container h2:hover,.read-mode #article-container h3:hover,.read-mode #article-container h4:hover,.read-mode #article-container h5:hover,.read-mode #article-container h6:hover {
padding: 0
}
.read-mode #article-container li:hover:before,.read-mode #article-container ol:hover:before,.read-mode #article-container ul:hover:before {
-webkit-transform: none!important;
-moz-transform: none!important;
-o-transform: none!important;
-ms-transform: none!important;
transform: none!important
}
.read-mode #article-container li:before,.read-mode #article-container ol:before {
background: 0 0!important;
color: var(--font-color)!important
}
.read-mode #article-container ul>li:before {
border-color: var(--gray)!important
}
.read-mode #article-container .tabs {
border: 2px solid var(--tab-border-color)
}
.read-mode #article-container .tabs>.nav-tabs {
background: 0 0
}
.read-mode #article-container .tabs>.nav-tabs>.tab {
border-top: none!important
}
.read-mode #article-container .tabs>.tab-contents .tab-item-content.active {
-webkit-animation: none;
-moz-animation: none;
-o-animation: none;
-ms-animation: none;
animation: none
}
.read-mode #article-container code {
color: var(--font-color)
}
.read-mode #article-container blockquote {
border-color: var(--gray);
background-color: var(--readmode-light-color)
}
.read-mode #article-container kbd {
border: 1px solid var(--gray);
background-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
color: var(--font-color)
}
.read-mode #article-container .hide-toggle {
border: 1px solid var(--gray)!important
}
.read-mode #article-container .btn-anzhiyu,.read-mode #article-container .hide-button,.read-mode #article-container .hl-label {
border: 1px solid var(--gray)!important;
background: var(--readmode-light-color)!important;
color: var(--font-color)!important
}
.read-mode #article-container .note {
border: 2px solid var(--gray);
border-left-color: var(--gray)!important;
filter: none;
background-color: var(--readmode-light-color)!important;
color: var(--font-color)
}
.read-mode #article-container .note .note-icon,.read-mode #article-container .note:before {
color: var(--font-color)
}

View File

@ -0,0 +1,68 @@
/* 相关推荐 */
.relatedPosts-list {
display: flex;
flex-wrap: wrap;
}
.relatedPosts>.relatedPosts-list>div {
background: #363636;
transition: 0.3s;
cursor: pointer;
overflow: hidden;
}
.relatedPosts>.relatedPosts-list>div {
position: relative;
display: inline-block;
overflow: hidden;
margin: 3px;
width: calc(33.333% - 6px);
height: 200px;
/* background: var(--heo-main); */
vertical-align: bottom;
}
.relatedPosts>.relatedPosts-list .cover {
width: 100%;
height: 100%;
opacity: 0.4;
transition: all 0.6s ease 0s;
object-fit: cover;
}
.relatedPosts>.relatedPosts-list .content {
position: absolute;
top: 50%;
padding: 0px 1rem;
width: 100%;
transform: translate(0px, -50%);
}
.relatedPosts>.relatedPosts-list .content .date {
color: var(--heo-fontcolor);
}
.relatedPosts>.relatedPosts-list .content .date {
color: var(--light-grey);
font-size: 90%;
}
.relatedPosts>.relatedPosts-list .content .title {
color: var(--white);
-webkit-line-clamp: 2;
}
.relatedPosts>.relatedPosts-list .content .title {
color: var(--heo-fontcolor);
font-weight: bold;
line-height: 1.5;
-webkit-line-clamp: 4;
font-size: 0.9rem;
text-align: center;
}
.relatedPosts > .relatedPosts-list > div:hover .cover {
opacity: 0.8;
transform: scale(1.1);
}

View File

@ -0,0 +1,91 @@
.relatedPosts-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
flex-direction: column;
}
.relatedPosts>.relatedPosts-list>div {
position: relative;
display: inline-block;
overflow: hidden;
margin: 3px;
width: calc(33.333% - 6px);
height: 200px;
background: var(--heo-main);
vertical-align: bottom;
}
.relatedPosts>.relatedPosts-list>div {
background: var(--heo-secondbg);
border: var(--style-border);
transition: .3s;
cursor: pointer;
overflow: hidden;
width: 100%;
margin-bottom: 8px
}
.relatedPosts>.relatedPosts-list>div:hover {
background: var(--heo-main)
}
@media screen and (max-width: 768px) {
.relatedPosts {
display: none
}
.relatedPosts>.relatedPosts-list>div {
border-radius: 4px
}
}
.relatedPosts>.relatedPosts-list>div:hover a .title {
color: var(--heo-white)
}
.relatedPosts>.relatedPosts-list .content .title {
color: var(--heo-white);
-webkit-line-clamp: 2;
margin-right: auto;
}
.relatedPosts>.relatedPosts-list .content .title {
color: var(--heo-fontcolor);
font-weight: 700;
line-height: 1.5;
-webkit-line-clamp: 4;
font-size: .9rem;
text-align: left;
overflow: hidden
}
.relatedPosts>.relatedPosts-list .content {
padding: 0 1rem;
width: 100%;
}
.relatedPosts>.relatedPosts-list .is-center {
text-align: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
flex-direction: row;
align-items: center;
}
.relatedPosts>.relatedPosts-list .content .date {
color: var(--heo-fontcolor);
display: none
}
.relatedPosts>.relatedPosts-list .cover {
width: 360px;
min-width: 45%;
height: 100%;
transition: all .6s ease 0s;
object-fit: cover;
filter: brightness(.9);
max-width: 45%;
}

View File

@ -0,0 +1,87 @@
.timeline {
width: 100%;
height: 20px;
background-color: var(--heo-background);
position: relative;
overflow: hidden;
margin-bottom: 20px;
border-radius: 0.5rem;
height: 2.5rem;
}
.progress {
width: 0;
height: 100%;
background-color: var(--heo-main);
position: absolute;
animation: progressAnimation 2s linear forwards;
animation-delay: -0.1s;
border-radius: 0.5rem
}
.past-time {
width: 2px;
height: 20px;
background-color: #3498db;
position: absolute;
transform-origin: left;
animation: pastTimeAnimation 3s linear forwards;
}
.percentage-label {
position: absolute;
left: 0;
font-size: 14px;
color: var(--heo-card-bg);
font-weight: bold;
top: 10px;
white-space: nowrap;
transition: left 0.5s linear;
visibility: hidden;
}
.time-labels {
display: flex;
justify-content: space-between;
width: 100%;
}
.time-labels>div {
font-size: 14px;
color: var(--heo-fontcolor);
}
@keyframes progressAnimation {
0% {
width: 0;
}
100% {
width: var(--progress-percentage, 0);
}
}
@keyframes pastTimeAnimation {
0% {
transform: scaleX(0);
}
100% {
transform: scaleX(var(--past-time-percentage, 0));
}
}
.timeline:hover {
animation: btn31-eff 3s linear infinite;
cursor: pointer;
}
@keyframes btn31-eff {
0% {
box-shadow: 0 0 2px var(--heo-main);
}
50% {
box-shadow: 0 0 40px var(--heo-main);
}
100% {
box-shadow: 0 0 2px var(--heo-main);
}
}

View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset = UTF-8" />
<title>互动友链</title>
<style>
body {
overflow: hidden;
background-color: #000000;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
}
.gdtx img {
position: absolute;
left: -120px;
top: -120px;
width: 240px;
height: 240px;
border-radius: 150px;
}
</style>
</head>
<body>
<div id="canvas" style="width: 540px;height: 640px;"></div>
<script src="/themes/theme-hao/assets/libs/link/protoclass.min.js"></script>
<script src="/themes/theme-hao/assets/libs/link/box2d.min.js"></script>
<script src="/themes/theme-hao/assets/libs/link/Main.min.js">
</script>
</body>
</html>

View File

@ -0,0 +1,539 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,734 @@
@font-face {
font-family: "haofont"; /* Project id 4159149 */
src: url('iconfont.eot?t=1708243411223'); /* IE9 */
src: url('iconfont.eot?t=1708243411223#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('iconfont.woff2?t=1708243411223') format('woff2'),
url('iconfont.woff?t=1708243411223') format('woff'),
url('iconfont.ttf?t=1708243411223') format('truetype'),
url('iconfont.svg?t=1708243411223#haofont') format('svg');
}
.haofont {
font-family: "haofont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.hao-icon-tushu:before {
content: "\eac6";
}
.hao-icon-screen:before {
content: "\e65b";
}
.hao-icon-yinle:before {
content: "\e65c";
}
.hao-icon-youxi:before {
content: "\e8a1";
}
.hao-icon-dianying:before {
content: "\e62b";
}
.hao-icon-star-full:before {
content: "\e9a1";
}
.hao-icon-star:before {
content: "\e9a2";
}
.hao-icon-star-half:before {
content: "\e9a3";
}
.hao-icon-baibanwenjian-daochu:before {
content: "\e612";
}
.hao-icon-moon-clear-fill:before {
content: "\e821";
}
.hao-icon-eicon_train-line:before {
content: "\e698";
}
.hao-icon-disc-fill:before {
content: "\e6fd";
}
.hao-icon-signal-tower-fill:before {
content: "\e6f2";
}
.hao-icon-search--line:before {
content: "\e697";
}
.hao-icon-chat--fill:before {
content: "\e6b2";
}
.hao-icon-apps-fill:before {
content: "\e82d";
}
.hao-icon-Home:before {
content: "\e69a";
}
.hao-icon-yingwen:before {
content: "\e6d6";
}
.hao-icon-jianti:before {
content: "\e6d7";
}
.hao-icon-fanti:before {
content: "\e6d8";
}
.hao-icon-aifadian-line:before {
content: "\e695";
}
.hao-icon-zhanghao1:before {
content: "\e696";
}
.hao-icon-zuozhe:before {
content: "\e694";
}
.hao-icon-weixin1:before {
content: "\e693";
}
.hao-icon-bianji:before {
content: "\e691";
}
.hao-icon-check-circle:before {
content: "\e77d";
}
.hao-icon-dashboard:before {
content: "\e6f7";
}
.hao-icon-bullseye:before {
content: "\eaff";
}
.hao-icon-logo-moment:before {
content: "\e690";
}
.hao-icon-leetcode:before {
content: "\ebf2";
}
.hao-icon-gitlab:before {
content: "\e692";
}
.hao-icon-csdn:before {
content: "\e68a";
}
.hao-icon-dribbble:before {
content: "\e87f";
}
.hao-icon-yuque:before {
content: "\e880";
}
.hao-icon-linkedin:before {
content: "\e73b";
}
.hao-icon-youtube:before {
content: "\e765";
}
.hao-icon-Instagram:before {
content: "\e68b";
}
.hao-icon-slack:before {
content: "\eca1";
}
.hao-icon-baidu:before {
content: "\e68c";
}
.hao-icon-discord-line:before {
content: "\e7af";
}
.hao-icon-cnblogs:before {
content: "\e68d";
}
.hao-icon-juejin:before {
content: "\e68e";
}
.hao-icon-steam:before {
content: "\ec22";
}
.hao-icon-telegram:before {
content: "\ec25";
}
.hao-icon-toutiao:before {
content: "\e68f";
}
.hao-icon-weixin:before {
content: "\e686";
}
.hao-icon-douban:before {
content: "\e687";
}
.hao-icon-29:before {
content: "\e688";
}
.hao-icon-weixingongzhonghao:before {
content: "\e689";
}
.hao-icon-cainixihuan:before {
content: "\e684";
}
.hao-icon-eicon_map-2-line1:before {
content: "\e685";
}
.hao-icon-yuan:before {
content: "\e833";
}
.hao-icon-creative-commons-nd-line:before {
content: "\e67a";
}
.hao-icon-creative-commons-by-line:before {
content: "\e67b";
}
.hao-icon-creative-commons-nc-line:before {
content: "\e67c";
}
.hao-icon-copyright-line:before {
content: "\e67d";
}
.hao-icon-font:before {
content: "\e67e";
}
.hao-icon-stopwatch:before {
content: "\e67f";
}
.hao-icon-file-lines:before {
content: "\e680";
}
.hao-icon-square-poll-vertical:before {
content: "\e681";
}
.hao-icon-universal-access:before {
content: "\e682";
}
.hao-icon-hourglass-start:before {
content: "\e683";
}
.hao-icon-tongxunlu07:before {
content: "\e679";
}
.hao-icon-arrow-right:before {
content: "\e600";
}
.hao-icon-arrow-left:before {
content: "\e601";
}
.hao-icon-dice:before {
content: "\e602";
}
.hao-icon-copy:before {
content: "\e603";
}
.hao-icon-cube:before {
content: "\e604";
}
.hao-icon-circle-arrow-right:before {
content: "\e605";
}
.hao-icon-clock:before {
content: "\e606";
}
.hao-icon-book:before {
content: "\e607";
}
.hao-icon-calendar-alt:before {
content: "\e608";
}
.hao-icon-eye-outline:before {
content: "\e609";
}
.hao-icon-circle-half-stroke:before {
content: "\e60a";
}
.hao-icon-arrow-up:before {
content: "\e60b";
}
.hao-icon-file-word:before {
content: "\e60c";
}
.hao-icon-fire:before {
content: "\e60d";
}
.hao-icon-dove:before {
content: "\e60e";
}
.hao-icon-gear:before {
content: "\e60f";
}
.hao-icon-inbox:before {
content: "\e610";
}
.hao-icon-history:before {
content: "\e611";
}
.hao-icon-message:before {
content: "\e613";
}
.hao-icon-moon:before {
content: "\e614";
}
.hao-icon-shapes:before {
content: "\e615";
}
.hao-icon-shuffle:before {
content: "\e616";
}
.hao-icon-language:before {
content: "\e617";
}
.hao-icon-tags:before {
content: "\e618";
}
.hao-icon-train:before {
content: "\e619";
}
.hao-icon-warning:before {
content: "\e61a";
}
.hao-icon-circle-arrow-up-right-1:before {
content: "\e61b";
}
.hao-icon-fish:before {
content: "\e61c";
}
.hao-icon-envelope:before {
content: "\e61d";
}
.hao-icon-music:before {
content: "\e61e";
}
.hao-icon-fan:before {
content: "\e61f";
}
.hao-icon-heartbeat-bold:before {
content: "\e620";
}
.hao-icon-link:before {
content: "\e621";
}
.hao-icon-chevron-left:before {
content: "\e622";
}
.hao-icon-rocket:before {
content: "\e623";
}
.hao-icon-lightbulb:before {
content: "\e624";
}
.hao-icon-shoe-prints:before {
content: "\e625";
}
.hao-icon-images:before {
content: "\e626";
}
.hao-icon-box-archive:before {
content: "\e627";
}
.hao-icon-artstation:before {
content: "\e628";
}
.hao-icon-paper-plane:before {
content: "\e629";
}
.hao-icon-house-chimney:before {
content: "\e62a";
}
.hao-icon-bars:before {
content: "\e62c";
}
.hao-icon-arrows-left-right:before {
content: "\e62d";
}
.hao-icon-book-open:before {
content: "\e62e";
}
.hao-icon-list-ul:before {
content: "\e62f";
}
.hao-icon-comment-sms:before {
content: "\e631";
}
.hao-icon-angles-right:before {
content: "\e632";
}
.hao-icon-tag:before {
content: "\e633";
}
.hao-icon-chevron-right:before {
content: "\e634";
}
.hao-icon-radio:before {
content: "\e635";
}
.hao-icon-forward:before {
content: "\e636";
}
.hao-icon-window-restore:before {
content: "\e637";
}
.hao-icon-backward:before {
content: "\e638";
}
.hao-icon-download:before {
content: "\e639";
}
.hao-icon-comment-medical:before {
content: "\e63a";
}
.hao-icon-paste:before {
content: "\e63b";
}
.hao-icon-arrow-rotate-right:before {
content: "\e63c";
}
.hao-icon-play:before {
content: "\e63d";
}
.hao-icon-circle-xmark:before {
content: "\e63e";
}
.hao-icon-angle-down:before {
content: "\e63f";
}
.hao-icon-chart-line:before {
content: "\e640";
}
.hao-icon-pencil:before {
content: "\e641";
}
.hao-icon-thumbtack:before {
content: "\e642";
}
.hao-icon-location-dot:before {
content: "\e643";
}
.hao-icon-fw-fire:before {
content: "\e644";
}
.hao-icon-calendar-days:before {
content: "\e645";
}
.hao-icon-angle-right:before {
content: "\e646";
}
.hao-icon-dice-d20:before {
content: "\e647";
}
.hao-icon-instagram:before {
content: "\e648";
}
.hao-icon-xmark:before {
content: "\e649";
}
.hao-icon-spinner:before {
content: "\e64a";
}
.hao-icon-bullhorn:before {
content: "\e64b";
}
.hao-icon-stream:before {
content: "\e64c";
}
.hao-icon-caret-left:before {
content: "\e64d";
}
.hao-icon-folder-open:before {
content: "\e64e";
}
.hao-icon-thumbs-up:before {
content: "\e64f";
}
.hao-icon-angle-double-down:before {
content: "\e650";
}
.hao-icon-sign-out-alt:before {
content: "\e651";
}
.hao-icon-angle-double-left:before {
content: "\e652";
}
.hao-icon-angle-double-right:before {
content: "\e653";
}
.hao-icon-angle-left:before {
content: "\e654";
}
.hao-icon-fw-eye:before {
content: "\e655";
}
.hao-icon-repeat:before {
content: "\e656";
}
.hao-icon-shuffle1:before {
content: "\e657";
}
.hao-icon-arrows-rotate:before {
content: "\e658";
}
.hao-icon-pause:before {
content: "\e659";
}
.hao-icon-heartbeat:before {
content: "\e65a";
}
.hao-icon-heartbeat1:before {
content: "\e65d";
}
.hao-icon-rss:before {
content: "\e65e";
}
.hao-icon-qq:before {
content: "\e65f";
}
.hao-icon-github:before {
content: "\e660";
}
.hao-icon-bilibili:before {
content: "\e661";
}
.hao-icon-paper-plane1:before {
content: "\e662";
}
.hao-icon-hashtag:before {
content: "\e663";
}
.hao-icon-hand-heart-fill:before {
content: "\e664";
}
.hao-icon-plant-fill:before {
content: "\e665";
}
.hao-icon-qrcode:before {
content: "\e666";
}
.hao-icon-weibo:before {
content: "\e667";
}
.hao-icon-copyright:before {
content: "\e668";
}
.hao-icon-bolt:before {
content: "\e669";
}
.hao-icon-circle-info:before {
content: "\e66a";
}
.hao-icon-triangle-exclamation:before {
content: "\e66b";
}
.hao-icon-circle-check:before {
content: "\e66c";
}
.hao-icon-circle-minus:before {
content: "\e66d";
}
.hao-icon-circle-plus:before {
content: "\e66e";
}
.hao-icon-circle-dot:before {
content: "\e66f";
}
.hao-icon-scissors:before {
content: "\e670";
}
.hao-icon-arrow-down:before {
content: "\e671";
}
.hao-icon-dengpao:before {
content: "\e672";
}
.hao-icon-danmu:before {
content: "\e673";
}
.hao-icon-zonglan:before {
content: "\e674";
}
.hao-icon-linggan:before {
content: "\e675";
}
.hao-icon-sanmingzhi:before {
content: "\e676";
}
.hao-icon-keyboard:before {
content: "\e677";
}
.hao-icon-tiktok:before {
content: "\e678";
}

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
templates/assets/images/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,10 @@
<svg width="80px" height="80px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="lds-disk">
<g transform="translate(50,50)">
<g ng-attr-transform="scale({{config.scale}})" transform="scale(0.6)">
<circle cx="0" cy="0" r="50" ng-attr-fill="{{config.c1}}" fill="#FFA500"></circle>
<circle cx="0" ng-attr-cy="{{config.cy}}" ng-attr-r="{{config.r}}" ng-attr-fill="{{config.c2}}" cy="-28" r="15" fill="#fff8eb" transform="rotate(312)">
<animateTransform attributeName="transform" type="rotate" calcMode="linear" values="0 0 0;360 0 0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animateTransform>
</circle>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

BIN
templates/assets/js/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,66 @@
(() => {
if (!document.getElementById('post-comment')) return
const initArtalk = () => {
window.artalkItem = Artalk.init(Object.assign({
el: '#artalk-wrap',
server: GLOBAL_CONFIG.source.artalk.artalkUrl,
site: GLOBAL_CONFIG.source.artalk.siteName,
pageKey: location.pathname.replace(/\/page\/\d$/, ""),
darkMode: false,
countEl: '#ArtalkCount'
}, null))
function versionOld(ctx){
// 旧版本兼容性补丁
ctx.getCommentList().forEach(comment => {
const $content = comment.getRender().$content
btf.loadLightbox($content.querySelectorAll('img:not([atk-emoticon])'))
})
}
function version_2_7_3_WithUpper(ctx){
// 2.7.3 版本及以后版本支持
ctx.get('list').getCommentNodes().forEach(comment => {
const $content = comment .getRender().$content
btf.loadLightbox($content.querySelectorAll('img:not([atk-emoticon])'))
})
}
function versionCheck(ctx){
if(ctx.getCommentList != undefined){
// Artalk 版本小于于 2.7.3
versionOld(ctx);
}else{
version_2_7_3_WithUpper(ctx);
}
}
if (GLOBAL_CONFIG.lightbox === 'null') return
window.artalkItem.on('list-loaded', () => {
versionCheck(window.artalkItem.ctx);
})
}
const loadArtalk = async () => {
if (typeof window.artalkItem === 'object') initArtalk()
else {
await getCSS(GLOBAL_CONFIG.source.artalk.css)
await getScript(GLOBAL_CONFIG.source.artalk.js)
initArtalk()
}
}
function setDarkMode() {
if (typeof window.artalkItem !== 'object') return
let isDark = document.documentElement.getAttribute('data-theme') === 'dark'
window.artalkItem.setDarkMode(!isDark)
}
if ('Artalk' === 'Artalk' || !GLOBAL_CONFIG.source.comments.lazyload) {
if (GLOBAL_CONFIG.source.comments.lazyload) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
else loadArtalk()
} else {
window.loadOtherComment = loadArtalk
}
})()

View File

@ -0,0 +1,64 @@
(() => {
if (!document.getElementById('post-comment')) return
const init = () => {
twikoo.init(Object.assign({
el: '#twikoo-wrap',
envId: GLOBAL_CONFIG.source.twikoo.twikooUrl,
region: '',
path: location.pathname.replace(/\/page\/\d$/, ""),
onCommentLoaded: function () {
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
typeof hljs === 'object' && hljs.highlightAll()
typeof Prism === 'object' && Prism.highlightAll()
$("input").focus(function () {
heo_intype = true;
});
$("textarea").focus(function () {
heo_intype = true;
});
$("input").focusout(function () {
heo_intype = false;
});
$("textarea").focusout(function () {
heo_intype = false;
});
}
}, null))
}
const getCount = () => {
twikoo.getCommentsCount({
envId: GLOBAL_CONFIG.source.twikoo.twikooUrl,
region: '',
urls: [window.location.pathname],
includeReply: true
}).then(function (res) {
document.getElementById('twikoo-count').innerText = res[0].count
}).catch(function (err) {
});
}
const runFn = () => {
init()
true && getCount()
}
const loadTwikoo = () => {
if (typeof twikoo === 'object') {
setTimeout(runFn, 0)
return
}
getScript(GLOBAL_CONFIG.source.twikoo.js).then(runFn)
}
if ('Twikoo' === 'Twikoo' || !GLOBAL_CONFIG.source.comments.lazyload) {
if (GLOBAL_CONFIG.source.comments.lazyload) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
else loadTwikoo()
} else {
window.loadOtherComment = () => {
loadTwikoo()
}
}
})()

View File

@ -0,0 +1,29 @@
(() => {
if (!document.getElementById('post-comment')) return
function initWaline() {
const waline = Waline.init(Object.assign({
el: '#waline-wrap',
serverURL: GLOBAL_CONFIG.source.waline.serverURL,
pageview: false,
dark: 'html[data-theme="dark"]',
path: window.location.pathname.replace(/\/page\/\d$/, ""),
comment: false,
locale:GLOBAL_CONFIG.source.waline.locale
}, null))
}
const loadWaline = async () => {
if (typeof Waline === 'object') initWaline()
else {
await getScript(GLOBAL_CONFIG.source.waline.js)
initWaline()
}
}
if ('Waline' === 'Waline' || !GLOBAL_CONFIG.source.comments.lazyload) {
if (GLOBAL_CONFIG.source.comments.lazyload) btf.loadComment(document.getElementById('waline-wrap'), loadWaline)
else setTimeout(loadWaline, 0)
} else {
window.loadOtherComment = loadWaline
}
})()

View File

@ -0,0 +1,733 @@
/* 获取直属子元素 */
function getChildren(el, className) {
for (let item of el.children) if (item.className === className) return item;
return null;
}
function parseExpression(expression, occupied) {
if (expression === "${full}") {
return occupied;
}
const match = expression.replaceAll("full", occupied).match(/^\$\{([<>=]{1,2}.+)\?(.+):(.+)}$/);
if (match) {
return eval(`occupied${match[1]} ? ${match[2]} : ${match[3]}`);
}
throw new Error(`Invalid expression "${expression}"`);
}
function extractHeight(occupied, width, height) {
const occupiedWidth = width.endsWith("%")
? occupied * (Number(width.slice(0, -1)) / 100)
: Number(width);
height = height.replaceAll("cwidth", occupiedWidth);
if (height.startsWith("${") && height.endsWith("}")) {
return parseExpression(height, occupied);
} else {
return height;
}
}
// 跳转链接的卡片
document.addEventListener("DOMContentLoaded", () => {
// 分栏 tab
customElements.define(
"hao-tabs",
class HaoTabs extends HTMLElement {
constructor() {
super();
this.options = {
id: this.getAttribute("id") || '',
index: this.getAttribute("index") || ''
};
const id = this.options.id
const index = this.options.index
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let navs = "";
let contents = "";
let newIndex = 0;
_innerHTML.replace(
/{tabs-item([^}]*)}([\s\S]*?){\/tabs-item}/g,
function ($0, $1, $2) {
newIndex +=1;
let active =''
if(index!='' && index!=null){
if(newIndex == index){
active = 'active';
}
}else{
if(newIndex==1){
active = 'active'
}
}
navs += `
<li class="tab ${active}"><button type="button" data-href="#${id}-${newIndex}">${$1}</button></li>
`;
contents += `
<div class="tab-item-content ${active}" id="${id}-${newIndex}">
${$2.trim().replace(/^(<br>)|(<br>)$/g, "")}
<button type="button" class="tab-to-top" aria-label="scroll to top"><i class="haofont hao-icon-arrow-up"></i></button>
</div>
`;
}
);
let htmlStr = `
<div class="tabs" id="${this.options.id}">
<ul class="nav-tabs">${navs}</ul>
<div class="tab-contents">${contents}</div>
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// 彩虹虚线
customElements.define(
"hao-dotted",
class DottedDom extends HTMLElement {
constructor() {
super();
this.startColor = this.getAttribute("begin") || "#ff6c6c";
this.endColor = this.getAttribute("end") || "#1989fa";
this.innerHTML = `
<span class="tool_dotted" style="background-image: repeating-linear-gradient(-45deg, ${this.startColor} 0, ${this.startColor} 20%, transparent 0, transparent 25%, ${this.endColor} 0, ${this.endColor} 45%, transparent 0, transparent 50%)"></span>
`;
}
}
);
// 进度条
customElements.define(
"hao-progress",
class ProgressDom extends HTMLElement {
constructor() {
super();
this.options = {
percentage: /^\d{1,3}%$/.test(this.getAttribute("pct"))
? this.getAttribute("pct")
: "50%",
color: this.getAttribute("color") || "#ff6c6c",
};
this.innerHTML = `
<span class="tool_progress">
<div class="tool_progress__strip">
<div class="tool_progress__strip-percent" style="width: ${this.options.percentage}; background: ${this.options.color};"></div>
</div>
<div class="tool_progress__percentage">${this.options.percentage}</div>
</span>
`;
}
}
);
// 小标记
customElements.define(
"hao-sign",
class SignDom extends HTMLElement {
constructor() {
super();
this.options = {
type: this.getAttribute("type"), // 小标签类型
content: this.innerHTML, // 内容
};
this.render();
}
render() {
this.innerHTML = `<span class="${this.options.type}">${this.options.content}</span>`;
}
}
);
// B站视频
customElements.define(
"hao-bilibili",
class BiliBiliDom extends HTMLElement {
constructor() {
super();
this.options = {
bvid: this.getAttribute("bvid"),
page: +(this.getAttribute("page") || "1"),
width: this.getAttribute("width") || "100%",
height: this.getAttribute("height") || "500",
autoplay: this.getAttribute("autoplay") || 0,
};
this.render();
}
render() {
if (!this.options.bvid) return (this.innerHTML = "请填写正确的bvid");
const realHeight = extractHeight(this.parentElement.offsetWidth, this.options.width, this.options.height);
this.setAttribute("height", realHeight);
this.innerHTML = `
<iframe class="iframe-dom" allowfullscreen="true" scrolling="no" border="0" frameborder="no" framespacing="0" class="tool_vplayer" src="//player.bilibili.com/player.html?bvid=${this.options.bvid}&page=${this.options.page}&autoplay=${this.options.autoplay}" style="width:${this.options.width}; height:${realHeight}px;"></iframe>`;
}
}
);
// pdf
customElements.define(
"hao-pdf",
class PDFDom extends HTMLElement {
constructor() {
super();
this.options = {
src: this.getAttribute("src") || "",
width: this.getAttribute("width") || "100%",
height: this.getAttribute("height") || "500",
};
this.render();
}
render() {
if (!this.options.src) return (this.innerHTML = "请填写正确的pdf链接");
const realHeight = extractHeight(this.parentElement.offsetWidth, this.options.width, this.options.height);
this.setAttribute("height", realHeight);
this.innerHTML = `
<div class="tool_pdf">
<iframe class="iframe-dom" src="${this.options.src}" style="width:${this.options.width}; height:${realHeight}px;"></iframe>
</div>`;
}
}
);
customElements.define(
"hao-introduction-card",
class HaoIntroductionCard extends HTMLElement {
constructor() {
super();
this.options = {
link: this.getAttribute("link") || 'https://0206.ink/',
img: this.getAttribute("img"),
tip: this.getAttribute("tip") || '小标题',
cardTitle: this.getAttribute("cardTitle") || '标题',
logo: this.getAttribute("logo"),
title: this.getAttribute("title"),
subTitle: this.getAttribute("subTitle"),
};
let style1 = ''
let style2 = ''
if(this.options.logo==null && this.options.title==null && this.options.subTitle==null){
style1 = 'height:416px'
style2 = 'height:100%;border-radius:15px'
}
let innerHTMLs = `
<div class="introduction-card" style="${style1}">
<div class="introduction-card-top no-lightbox" style="${style2}">
<div class="int-card-info">
<div class="int-tip">${this.options.tip}</div>
<div class="int-cardTitle">${this.options.cardTitle}</div>
</div>
<img ${GLOBAL_CONFIG.source.img.src}="${this.options.img}" alt="introduction">
</div>
`;
if(this.options.logo!=null && this.options.title!=null && this.options.subTitle!=null){
innerHTMLs += `
<div class="introduction-card-bottom">
<div class="left no-lightbox">
<img ${GLOBAL_CONFIG.source.img.src}="${this.options.logo}" alt="introduction">
<div class="info">
<div class="title">${this.options.title}</div>
<div class="subTitle">${this.options.subTitle}</div>
</div>
</div>
<div class="right">
<a href="${this.options.link}" tableindex="-1" class="no-text-decoration"
data-pjax-state="">前往
</a>
</div>
</div>
`;
}
innerHTMLs += `
</div>
`;
this.innerHTML = innerHTMLs;
}
}
);
// 折叠框 folding
customElements.define(
"hao-folding",
class HaoFolding extends HTMLElement {
constructor() {
super();
this.options = {
title: this.getAttribute("title"),
color: this.getAttribute("color") || '',
type: this.getAttribute("type") || ''
};
const _temp = getChildren(this, "_tpl");
let contents = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let htmlStr = `
<details class="folding-tag" ${this.options.color} ${this.options.type}>
<summary>${this.options.title}</summary>
<div class="content">
${contents}
</div>
</details>
`;
this.innerHTML = htmlStr;
}
}
);
// 链接卡片 link
customElements.define(
"hao-tag-link",
class HaoTagLink extends HTMLElement {
constructor() {
super();
this.options = {
link: this.getAttribute("link"),
logo: this.getAttribute("logo") || '',
title: this.getAttribute("title") || '',
described: this.getAttribute("described") || '',
};
let tagLinkLeft = `
<div class="tag-link-left">
<i class="haofont hao-icon-link"></i>
</div>`
if(this.options.logo!=null && this.options.logo!=''){
tagLinkLeft = `
<div class="tag-link-left"
style="background-image:url(${this.options.logo})">
</div>`
}
let htmlStr = `
<div calss="hao-tag-link">
<a class="tag-Link" target="_blank"
href="${this.options.link}" rel="external nofollow noreferrer"
draggable="false">
<div class="tag-link-tips">引用站外地址</div>
<div class="tag-link-bottom">
${tagLinkLeft}
<div class="tag-link-right">
<div class="tag-link-title">${this.options.title}</div>
<div class="tag-link-sitename">${this.options.described}</div>
</div><i class="haofont hao-icon-angle-right"></i>
</div>
</a>
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// Note (Bootstrap Callout)
customElements.define(
"hao-note",
class HaoNote extends HTMLElement {
constructor() {
super();
this.options = {
class: this.getAttribute("class") || '',
noIcon: this.getAttribute("noIcon") || '',
style: this.getAttribute("style") || ''
};
let htmlStr = `
<div class="note ${this.options.class} ${this.options.noIcon} ${this.options.style}">${this.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "")}</div>
`;
this.innerHTML = htmlStr;
}
}
);
// 上标标签 tip
customElements.define(
"hao-tip",
class HaoTip extends HTMLElement {
constructor() {
super();
this.options = {
class: this.getAttribute("class") || 'info',
noIcon: this.getAttribute("noIcon") || ''
};
let htmlStr = `
<div class="tip ${this.options.class} ${this.options.noIcon}">${this.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "")}</div>
`;
this.innerHTML = htmlStr;
}
}
);
// timeline
customElements.define(
"hao-timeline",
class HaoTimeline extends HTMLElement {
constructor() {
super();
this.options = {
title: this.getAttribute("title") || '',
color: this.getAttribute("color") || ''
};
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let content = "";
_innerHTML.replace(
/{timeline-item([^}]*)}([\s\S]*?){\/timeline-item}/g,
function ($0, $1, $2) {
content += `
<div class="timeline-item">
<div class="timeline-item-title">
<div class="item-circle">
<p>${$1}</p>
</div>
</div>
<div class="timeline-item-content">
${$2.trim().replace(/^(<br>)|(<br>)$/g, "")}
</div>
</div>
`;
}
);
let htmlStr = `
<div class="timeline ${this.options.color}">
<div class="timeline-item headline">
<div class="timeline-item-title">
<div class="item-circle">
<p>${this.options.title}</p>
</div>
</div>
</div>
${content}
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// 按钮 btns
customElements.define(
"hao-btns",
class HaoBtns extends HTMLElement {
constructor() {
super();
this.options = {
class: this.getAttribute("class") || '',
style: this.getAttribute("style") || '',
grid: this.getAttribute("grid") || '',
};
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let content = "";
if(this.options.class == 'rounded'){
_innerHTML.replace(
/{([^}]*)}/g,
function ($0, $1) {
var str = $1.split(",", 5);
if(str.length==5){
content += `
<a target="_blank" rel="noopener external nofollow noreferrer"
href="${str[2]}"
class="no-text-decoration"><i class="${str[4]}"></i> <b>${str[0]}</b>
<p class="p red">${str[1]}</p><img
${GLOBAL_CONFIG.source.img.src}="${str[3]}">
</a>
`;
}else{
content += `
<a class="button no-text-decoration" href="${str[1]}" title="${str[0]}">
<i class="${str[2]}"></i> ${str[0]}
</a>
`;
}
}
);
}
if(this.options.class == 'circle'){
_innerHTML.replace(
/{([^}]*)}/g,
function ($0, $1) {
var str = $1.split(",", 5);
if(str.length==5){
content += `
<a target="_blank" rel="noopener external nofollow noreferrer"
href="${str[2]}"
class="no-text-decoration"><i class="${str[4]}"></i> <b>${str[0]}</b>
<p class="p red">${str[1]}</p><img
${GLOBAL_CONFIG.source.img.src}="${str[3]}">
</a>
`;
}else{
content += `
<a class="button no-text-decoration" target="_blank" rel="noopener external nofollow noreferrer"
href="${str[1]}" title="${str[0]}">
<img
${GLOBAL_CONFIG.source.img.src}="${str[2]}"/>${str[0]}
</a>
`;
}
}
);
}
let htmlStr = `
<div class="btns ${this.options.class} ${this.options.style} ${this.options.grid}">
${content}
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// gallerygroup 相册图库
customElements.define(
"hao-gallery-group",
class HaoGalleryGroup extends HTMLElement {
constructor() {
super();
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let contents = "";
_innerHTML.replace(
/{([^}]*)}/g,
function ($0, $1) {
var str = $1.split(",",4);
contents += `
<figure class="gallery-group no-lightbox group-two"">
<img class="gallery-group-img"
${GLOBAL_CONFIG.source.img.src}="${str[3]}"
alt="Group Image Gallery" >
<figcaption>
<div class="gallery-group-name">${str[0]}</div>
<p>${str[1]}</p><a target="_blank" rel="noopener" href="${str[2]}"></a>
</figcaption>
</figure>
`;
}
);
let htmlStr = `
<div class="gallery-group-main">
${contents}
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// gallery 相册
customElements.define(
"hao-gallery",
class HaoGallery extends HTMLElement {
constructor() {
super();
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let contents = "";
_innerHTML.replace(
/{([^}]*)}/g,
function ($0, $1) {
var str = $1.split(",");
str.forEach((item) => {
contents += `
<div class="fj-gallery-item">
<img src="${item}">
</div>
`;
});
}
);
let htmlStr = `
<section class="page-1 loadings">
<div class="type-gallery ">
<div class="gallery">
${contents}
</div>
</div>
</section>
`;
this.innerHTML = htmlStr;
}
}
);
// flink 友链标签
customElements.define(
"hao-flink",
class HaoFlink extends HTMLElement {
constructor() {
super();
this.options = {
name: this.getAttribute("name"),
desc: this.getAttribute("desc"),
style: this.getAttribute("style"),
};
const _temp = getChildren(this, "_tpl");
let _innerHTML = _temp.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "");
let style = this.options.style;
let content = "";
let contents = "";
let class_desc = "";
_innerHTML.replace(
/{([^}]*)}/g,
function ($0, $1) {
var flink = $1.split(",",5);
if(style=='beautify'){
contents +=`
<div class="site-card">
<a class="img" target="_blank" href="${flink[1]}" title="${flink[0]}">
<img class="flink-avatar entered loaded" style="pointer-events: none;" alt="${flink[0]}" ${GLOBAL_CONFIG.source.img.src}="${flink[4] || flink[2]}" >
</a>
<a class="info cf-friends-link" target="_blank" href="${flink[1]}" title="${flink[0]}">
<div class="site-card-avatar no-lightbox">
<img class="flink-avatar cf-friends-avatar" alt="${flink[0]}" ${GLOBAL_CONFIG.source.img.src}="${flink[2]}">
</div>
<div class="site-card-text">
<span class="title cf-friends-name">${flink[0]}</span>
<span class="desc" title="${flink[3]}">${flink[3]}</span>
</div>
</a>
</div>
`
}
if(style=='default'){
contents +=`
<div class="flink-list-item">
<a class="cf-friends-link" rel="external nofollow" target="_blank" href="${flink[1]}" title="${flink[0]}">
<img class="flink-avatar cf-friends-avatar" alt="${flink[0]}" ${GLOBAL_CONFIG.source.img.src}="${flink[2]}">
<div class="flink-item-info no-lightbox">
<span class="flink-item-name cf-friends-name">${flink[0]}</span>
<span class="flink-item-desc" title="${flink[3]}">${flink[3]}</span>
<img ${GLOBAL_CONFIG.source.img.src}="${flink[2]}">
</div>
</a>
</div>
`
}
}
);
if(this.options.desc!=null && this.options.desc!=''){
class_desc =`
<div class="flink-desc">${this.options.desc}</div>
`
}
if(this.options.style=='beautify'){
content =`
<div class="site-card-group">
${contents}
</div>
`
}
if(this.options.style=='default'){
content =`
<div class="flink-list">
${contents}
</div>
`
}
let htmlStr = `
<div class="flink" id="article-container">
<div class="flink-name">${this.options.name}</div>
${class_desc}
${content}
</div>
`;
this.innerHTML = htmlStr;
}
}
);
// 复选列表 checkbox
customElements.define(
"hao-checkbox",
class HaoCheckbox extends HTMLElement {
constructor() {
super();
this.options = {
class: this.getAttribute("class") || '',
colour: this.getAttribute("colour") || '',
status: this.getAttribute("status") || ''
};
let htmlStr = `
<div class="checkbox ${this.options.class} ${this.options.colour} ${this.options.status}"><input type="checkbox" ${this.options.status}><p>${this.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "")}</p></div>
`;
this.innerHTML = htmlStr;
}
}
);
// tag-hide
customElements.define(
"hao-tag-hide",
class HaoCheckbox extends HTMLElement {
constructor() {
super();
this.options = {
display: this.getAttribute("display") || '查看',
bg: this.getAttribute("bg") || '',
color: this.getAttribute("color") || ''
};
let htmlStr = `
<span class="hide-inline">
<button type="button" class="hide-button" style="background-color:${this.options.bg};color:${this.options.color}">
${this.options.display}<br>
</button>
<span class="hide-content">${this.innerHTML.trim().replace(/^(<br>)|(<br>)$/g, "")}</span>
</span>
`;
this.innerHTML = htmlStr;
}
}
);
customElements.define(
"hao-dplayer",
class HaoDplayer extends HTMLElement {
constructor() {
super();
this.options = {
src: this.getAttribute("src") || "",
player:
this.getAttribute("player") ||
`/themes/theme-hao/assets/libs/dplayer/dplayer.html?url=`,
width: this.getAttribute("width") || "100%",
height: this.getAttribute("height") || "500px",
};
this.render();
}
render() {
if (this.options.src)
this.innerHTML = `<iframe allowfullscreen="true" class="hao_vplayer" src="${
this.options.player + this.options.src
}" style="width:${this.options.width};height:${
this.options.height
}"></iframe>`;
else this.innerHTML = "视频地址未填写!";
}
}
);
});

463
templates/assets/js/halo.js Normal file
View File

@ -0,0 +1,463 @@
let halo = {
darkComment: () => {
if (document.querySelector('#comment div').shadowRoot.querySelector('.halo-comment-widget').classList !=
null) {
let commentDOMclass = document.querySelector('#comment div').shadowRoot.querySelector(
'.halo-comment-widget').classList
if (commentDOMclass.contains('light'))
commentDOMclass.replace('light', 'dark')
else
commentDOMclass.replace('dark', 'light')
}
},
dataCodeTheme: () => {
var t = document.documentElement.getAttribute('data-theme')
var e = document.querySelector("link[data-code-theme=light]"),
o = document.querySelector("link[data-code-theme=dark]");
(o || e) && ("light" === t ? (o.disabled = !0, e.disabled = !1) : (e.disabled = !0, o.disabled = !1))
},
/**
* 代码
* 只适用于halo的代码渲染
*/
addPrismTool: () => {
if (typeof Prism === 'undefined' || typeof document === 'undefined') {
return;
}
if (!Prism.plugins.toolbar) {
console.warn('Copy to Clipboard plugin loaded before Toolbar plugin.');
return;
}
const enable = GLOBAL_CONFIG.prism.enable;
if (!enable) return;
const isEnableTitle = GLOBAL_CONFIG.prism.enable_title;
const isEnableHr = GLOBAL_CONFIG.prism.enable_hr;
const isEnableLine = GLOBAL_CONFIG.prism.enable_line;
const isEnableCopy = GLOBAL_CONFIG.prism.enable_copy;
const isEnableExpander = GLOBAL_CONFIG.prism.enable_expander;
const prismLimit = GLOBAL_CONFIG.prism.prism_limit;
const isEnableHeightLimit = GLOBAL_CONFIG.prism.enable_height_limit;
// https://stackoverflow.com/a/30810322/7595472
/** @param {CopyInfo} copyInfo */
function fallbackCopyTextToClipboard(copyInfo) {
var textArea = document.createElement('textarea');
textArea.value = copyInfo.getText();
// Avoid scrolling to bottom
textArea.style.top = '0';
textArea.style.left = '0';
textArea.style.position = 'fixed';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
setTimeout(function() {
if (successful) {
copyInfo.success();
} else {
copyInfo.error();
}
}, 1);
} catch (err) {
setTimeout(function() {
copyInfo.error(err);
}, 1);
}
document.body.removeChild(textArea);
}
/** @param {CopyInfo} copyInfo */
function copyTextToClipboard(copyInfo) {
if (navigator.clipboard) {
navigator.clipboard.writeText(copyInfo.getText()).then(copyInfo.success, function() {
// try the fallback in case `writeText` didn't work
fallbackCopyTextToClipboard(copyInfo);
});
} else {
fallbackCopyTextToClipboard(copyInfo);
}
}
/**
* Selects the text content of the given element.
*
* @param {Element} element
*/
function selectElementText(element) {
// https://stackoverflow.com/a/20079910/7595472
window.getSelection().selectAllChildren(element);
}
/**
* Traverses up the DOM tree to find data attributes that override the default plugin settings.
*
* @param {Element} startElement An element to start from.
* @returns {Settings} The plugin settings.
* @typedef {Record<"copy" | "copy-error" | "copy-success" | "copy-timeout", string | number>} Settings
*/
function getSettings(startElement) {
/** @type {Settings} */
var settings = {
'copy': 'Copy',
'copy-error': 'Press Ctrl+C to copy',
'copy-success': 'Copied!',
'copy-timeout': 5000
};
var prefix = 'data-prismjs-';
for (var key in settings) {
var attr = prefix + key;
var element = startElement;
while (element && !element.hasAttribute(attr)) {
element = element.parentElement;
}
if (element) {
settings[key] = element.getAttribute(attr);
}
}
return settings;
}
var r = Prism.plugins.toolbar.hook = function(a) {
var r = a.element.parentNode;
var toolbar = r.nextElementSibling;
//标题
isEnableTitle && toolbar.classList.add("c-title")
//标题分割线
isEnableHr && toolbar.classList.add("c-hr")
var customItem = document.createElement("div");
customItem.className = 'custom-item absolute top-0'
//复制
if (isEnableCopy) {
var copy = document.createElement("i");
copy.className = 'haofont hao-icon-paste copy-button code-copy cursor-pointer'
customItem.appendChild(copy)
copy.addEventListener('click', function() {
copyTextToClipboard({
getText: function() {
return a.element.textContent;
},
success: function() {
btf.snackbarShow('复制成功')
setState('copy-success');
resetText();
},
error: function() {
setState('copy-error');
setTimeout(function() {
selectElementText(a.element);
}, 1);
resetText();
}
});
});
}
const prismToolsFn = function(e) {
const $target = e.target.classList;
if ($target.contains("code-expander")) prismShrinkFn(this);
};
//折叠
if (isEnableExpander) {
var expander = document.createElement("i");
expander.className =
'fa-sharp fa-solid haofont hao-icon-angle-down code-expander cursor-pointer'
customItem.appendChild(expander)
expander.addEventListener('click', prismToolsFn)
}
const expandCode = function() {
this.classList.toggle("expand-done");
this.style.display = "none";
r.classList.toggle("expand-done");
};
if (isEnableHeightLimit && r.offsetHeight > prismLimit) {
r.classList.add("close")
const ele = document.createElement("div");
ele.className = "code-expand-btn";
ele.innerHTML = '<i class="haofont hao-icon-angle-double-down"></i>';
ele.addEventListener("click", expandCode);
r.offsetParent.appendChild(ele);
}
const prismShrinkFn = ele => {
const $nextEle = r.offsetParent.lastElementChild.classList
toolbar.classList.toggle('c-expander')
r.classList.toggle("expand-done-expander");
if (toolbar.classList.contains('c-expander')) {
r.firstElementChild.style.display = "none";
if ($nextEle.contains('code-expand-btn')) {
r.offsetParent.lastElementChild.style.display = "none";
}
} else {
r.firstElementChild.style.display = "block";
if ($nextEle.contains('code-expand-btn') && !r.classList.contains('expand-done')) {
r.offsetParent.lastElementChild.style.display = "block";
}
}
};
toolbar.appendChild(customItem)
var settings = getSettings(a.element);
function resetText() {
setTimeout(function() {
setState('copy');
}, settings['copy-timeout']);
}
/** @param {"copy" | "copy-error" | "copy-success"} state */
function setState(state) {
copy.setAttribute('data-copy-state', state);
}
};
Prism.hooks.add("complete", r)
},
addScript: (e, t, n) => {
if (document.getElementById(e))
return n ? n() : void 0;
let a = document.createElement("script");
a.src = t,
a.id = e,
n && (a.onload = n),
document.head.appendChild(a)
},
danmu: () => {
const e = new EasyDanmakuMin({
el: "#danmu",
line: 10,
speed: 20,
hover: !0,
loop: !0
});
let t = saveToLocal.get("danmu");
if (t)
e.batchSend(t, !0);
else {
let n = [];
if (GLOBAL_CONFIG.source.comments.use == 'Twikoo') {
fetch(GLOBAL_CONFIG.source.twikoo.twikooUrl, {
method: "POST",
body: JSON.stringify({
event: "GET_RECENT_COMMENTS",
accessToken: GLOBAL_CONFIG.source.twikoo.accessToken,
includeReply: !1,
pageSize: 5
}),
headers: {
"Content-Type": "application/json"
}
}).then((e => e.json())).then((({
data: t
}) => {
t.forEach((e => {
null == e.avatar && (e.avatar =
"https://cravatar.cn/avatar/d615d5793929e8c7d70eab5f00f7f5f1?d=mp"
),
n.push({
avatar: e.avatar,
content: e.nick + "" + btf.changeContent(e
.comment),
href: e.url + '#' + e.id
})
})),
e.batchSend(n, !0),
saveToLocal.set("danmu", n, .02)
}))
}
if (GLOBAL_CONFIG.source.comments.use == 'Artalk') {
const statheaderList = {
method: 'GET',
headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
'Origin': window.location.origin
}
// ,
// body: new URLSearchParams({
// 'site_name': GLOBAL_CONFIG.source.artalk.siteName,
// 'limit': '100',
// 'type': 'latest_comments'
// })
}
const queryParams = new URLSearchParams({
'site_name': GLOBAL_CONFIG.source.artalk.siteName,
'limit': '100'
});
fetch(GLOBAL_CONFIG.source.artalk.artalkUrl + 'api/v2/stats/latest_comments?' + queryParams.toString(),
statheaderList)
.then((e => e.json())).then((({
data: t
}) => {
t.forEach((e => {
n.push({
avatar: 'https://cravatar.cn/avatar/' + e
.email_encrypted + '?d=mp&s=240',
content: e.nick + "" + btf.changeContent(e
.content_marked),
href: e.page_url + '#atk-comment-' + e.id
})
})),
e.batchSend(n, !0),
saveToLocal.set("danmu", n, .02)
}))
}
if (GLOBAL_CONFIG.source.comments.use == 'Waline') {
const loadWaline = () => {
Waline.RecentComments({
serverURL: GLOBAL_CONFIG.source.waline.serverURL,
count: 50
}).then(({
comments
}) => {
const walineArray = comments.map(e => {
return {
'content': e.nick + "" + btf.changeContent(e.comment),
'avatar': e.avatar,
'href': e.url + '#' + e.objectId,
}
})
e.batchSend(walineArray, !0),
saveToLocal.set("danmu", walineArray, .02)
})
}
if (typeof Waline === 'object') loadWaline()
else getScript(GLOBAL_CONFIG.source.waline.js).then(loadWaline)
}
}
document.getElementById("danmuBtn").innerHTML =
"<button class=\"hideBtn\" onclick=\"document.getElementById('danmu').classList.remove('hidedanmu')\">显示弹幕</button> <button class=\"hideBtn\" onclick=\"document.getElementById('danmu').classList.add('hidedanmu')\">隐藏弹幕</button>"
},
changeMarginLeft(element) {
var randomMargin = Math.floor(Math.random() * 901) + 100; // 生成100-1000之间的随机数
element.style.marginLeft = randomMargin + 'px';
},
getTopSponsors() {
var user_id = GLOBAL_CONFIG.source.power.userId
var show_num = GLOBAL_CONFIG.source.power.showNum
function getPower() {
const url = GLOBAL_CONFIG.source.power.url + user_id
fetch(url)
.then(res => res.json())
.then(data => {
if (200 === data["ec"]) {
var values = data["data"]["list"]
saveToLocal.set('power-data', JSON.stringify(values), 10 / (60 * 24))
renderer(values);
}
})
}
function renderer(values) {
var data = getArrayItems(values, 1);
let powerStar = document.getElementById("power-star")
if (values.length === 0) {
powerStar.href = GLOBAL_CONFIG.source.power.powerLink
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')">
</div>
<div class="power-star-body">
<div id="power-star-title">还没有人赞助</div>
<div id="power-star-desc">为爱发电点击赞助</div>
</div>`;
} else {
if (powerStar) {
powerStar.href = "https://afdian.net/u/" + data[0].user_id
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url(${data[0].avatar})">
</div>
<div class="power-star-body">
<div id="power-star-title">${data[0].name}</div>
<div id="power-star-desc">更多支持为爱发电</div>
</div>`;
}
if (values.length > 1) {
var i = 0;
var htmlText = '';
for (let value of values) {
if (i > parseInt(show_num)) {
break;
}
htmlText +=
` <a href="${"https://afdian.net/u/" + value["user_id"]}" rel="external nofollow" target="_blank" th:title="${value["name"]}">${value["name"]}</a>`;
i = i + 1;
}
if (document.getElementById("power-item-link")) {
document.getElementById("power-item-link").innerHTML = htmlText;
}
}
}
}
function init() {
const data = saveToLocal.get('power-data')
if (data) {
renderer(JSON.parse(data))
} else {
getPower()
}
}
document.getElementById("power-star") && init()
},
checkAd() {
var default_enable = GLOBAL_CONFIG.source.footer.default_enable
if (default_enable) {
var adElement = document.getElementById("footer-banner");
var notMusic = document.body.getAttribute("data-type") != "music"; // 检测是否为音乐页面
if ((adElement.offsetWidth <= 0 || adElement.offsetHeight <= 0) && notMusic) {
// 元素不可见,可能被拦截
console.log("Element may be blocked by AdBlocker Ultimate");
alert("页脚信息可能被AdBlocker Ultimate拦截请检查广告拦截插件")
}
}
}
}

685
templates/assets/js/heo.js Normal file
View File

@ -0,0 +1,685 @@
let heo_cookiesTime = null
// 第一次播放音乐
,heo_musicFirst = false
// 音乐播放状态
,heo_musicPlaying = false
,heo_keyboard = false
,heo_intype = false
,lastSayHello = ""
,refreshNum = 1;
// 私有函数
var heo = {
// 检测显示模式
darkModeStatus: function () {
let theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
if (theme == 'light') {
$(".menu-darkmode-text").text("深色模式");
} else {
$(".menu-darkmode-text").text("浅色模式");
}
},
// 首页bb
initIndexEssay: function() {
if (document.querySelector("#bber-talk"))
$(".swiper-wrapper .swiper-slide").each(function () {
var text = $(this)[0].innerText;
if (text != 'undefined') {
$(this).text(btf.changeContent(text));
}
})
new Swiper(".swiper-container",{
direction: "vertical",
loop: !0,
autoplay: {
delay: 3e3,
pauseOnMouseEnter: !0
}
})
},
// 只在首页显示
onlyHome: function () {
var urlinfo = window.location.pathname;
urlinfo = decodeURIComponent(urlinfo);
if (urlinfo == '/') {
$('.only-home').attr('style', 'display: flex');
} else {
$('.only-home').attr('style', 'display: none');
}
},
//是否在首页
is_Post: function () {
var url = window.location.href; //获取url
if (url.indexOf("/archives/") >= 0) { //判断url地址中是否包含code字符串
return true;
} else {
return false;
}
},
//监测是否在页面开头
addNavBackgroundInit: function() {
var e = 0
, t = 0;
document.body && (e = document.body.scrollTop),
document.documentElement && (t = document.documentElement.scrollTop),
0 != (e - t > 0 ? e : t) && (document.getElementById("page-header").classList.add("nav-fixed"),
document.getElementById("page-header").classList.add("nav-visible"),
$("#cookies-window").hide())
},
tagPageActive: function() {
var e = window.location.pathname;
if (/\/tags\/.*?/.test(e = decodeURIComponent(e))) {
var t = e.split("/")[2];
if (document.querySelector("#tag-page-tags")) {
$("a").removeClass("select");
var o = document.getElementById(t);
o && (o.classList.add("select"),
o.style.order = "-1")
}
}
},
categoriesBarActive: function() {
document.querySelector("#category-bar") && $(".category-bar-item").removeClass("select");
var e = window.location.pathname;
if ("/" == (e = decodeURIComponent(e)))
document.querySelector("#category-bar") && document.getElementById("category-bar-home").classList.add("select");
else {
if (/\/categories\/.*?/.test(e)) {
var t = e.split("/")[2];
if (document.querySelector("#category-bar")) {
var o = document.getElementById(t);
o && (o.classList.add("select"),
o.style.order = "-1")
}
}
}
},
// 页脚友链
addFriendLinksInFooter: function () {
var footerRandomFriendsBtn = document.getElementById("footer-random-friends-btn");
if(!footerRandomFriendsBtn) return;
footerRandomFriendsBtn.style.opacity = "0.2";
footerRandomFriendsBtn.style.transitionDuration = "0.3s";
footerRandomFriendsBtn.style.transform = "rotate(" + 360 * refreshNum++ + "deg)";
function getLinks(){
const fetchUrl = "/apis/api.plugin.halo.run/v1alpha1/plugins/PluginLinks/links?keyword=&sort=priority,asc"
fetch(fetchUrl)
.then(res => res.json())
.then(json => {
saveToLocal.set('links-data', JSON.stringify(json.items), 10 / (60 * 24))
renderer(json.items);
})
}
function renderer(data){
const linksUrl = GLOBAL_CONFIG.source.links.linksUrl
const num = GLOBAL_CONFIG.source.links.linksNum
var randomFriendLinks = getArrayItems(data, num);
var htmlText = '';
for (let i = 0; i < randomFriendLinks.length; ++i) {
var item = randomFriendLinks[i]
htmlText += `<a class='footer-item' href='${item.spec.url}' target="_blank" rel="noopener nofollow">${item.spec.displayName}</a>`;
}
htmlText += `<a class='footer-item' href='${linksUrl}'>更多</a>`
if(document.getElementById("friend-links-in-footer")){
document.getElementById("friend-links-in-footer").innerHTML = htmlText;
}
}
function friendLinksInFooterInit(){
const data = saveToLocal.get('links-data')
if (data) {
renderer(JSON.parse(data))
} else {
getLinks()
}
setTimeout(()=>{
footerRandomFriendsBtn.style.opacity = "1";
}, 300)
}
friendLinksInFooterInit();
},
//禁止图片右键单击
stopImgRightDrag: function () {
var img = $("img");
img.on("dragstart", function () {
return false;
});
},
//置顶文章横向滚动
topPostScroll: function () {
if (document.getElementById("recent-post-top")) {
let xscroll = document.getElementById("recent-post-top");
xscroll.addEventListener("mousewheel", function (e) {
//计算鼠标滚轮滚动的距离
let v = -e.wheelDelta / 2;
xscroll.scrollLeft += v;
//阻止浏览器默认方法
if (document.body.clientWidth < 1300) {
e.preventDefault();
}
}, false);
}
},
topCategoriesBarScroll: function () {
if (document.getElementById("category-bar-items")) {
let xscroll = document.getElementById("category-bar-items");
xscroll.addEventListener("mousewheel", function (e) {
//计算鼠标滚轮滚动的距离
let v = -e.wheelDelta / 2;
xscroll.scrollLeft += v;
//阻止浏览器默认方法
e.preventDefault();
}, false);
}
},
//作者卡片问好
sayhi: function () {
if (GLOBAL_CONFIG.profileStyle == 'default') {
if (document.querySelector('#author-info__sayhi')) {
document.getElementById("author-info__sayhi").innerHTML = getTimeState() + "!我是";
}
}else{
if (document.querySelector('#author-info__sayhi')) {
document.getElementById("author-info__sayhi").innerHTML = getTimeState();
}
}
},
// 二维码
qrcodeCreate: function () {
if (document.getElementById('qrcode')) {
document.getElementById("qrcode").innerHTML = "";
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: window.location.href,
width: 250,
height: 250,
colorDark: "#000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
}
},
// 刷新即刻短文瀑布流
reflashEssayWaterFall: function() {
document.querySelector("#waterfall") && setTimeout((function() {
waterfall("#waterfall"),
document.getElementById("waterfall") && document.getElementById("waterfall").classList.add("show")
}
), 500)
},
// 下载图片
downloadImage: function (imgsrc, name) { //下载图片地址和图片名
rm.hideRightMenu();
if (rm.downloadimging == false) {
rm.downloadimging = true;
btf.snackbarShow('正在下载中,请稍后', false, 10000)
setTimeout(function () {
let image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
let a = document.createElement("a"); // 生成一个a元素
let event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "photo"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.dispatchEvent(event); // 触发a的单击事件
};
image.src = imgsrc;
btf.snackbarShow('图片已添加盲水印,请遵守版权协议');
rm.downloadimging = false;
}, "10000");
} else {
btf.snackbarShow('有正在进行中的下载,请稍后再试');
}
},
//控制评论弹幕
switchCommentBarrage: function () {
let commentBarrage = document.querySelector('.comment-barrage');
if (commentBarrage) {
if ($(".comment-barrage").is(":visible")) {
$(".comment-barrage").hide();
$(".menu-commentBarrage-text").text("显示热评");
document.querySelector("#consoleCommentBarrage").classList.remove("on");
localStorage.setItem('commentBarrageSwitch', 'false');
btf.snackbarShow("✨ 已关闭评论弹幕", false, 2000)
} else if ($(".comment-barrage").is(":hidden")) {
$(".comment-barrage").show();
$(".menu-commentBarrage-text").text("关闭热评");
document.querySelector("#consoleCommentBarrage").classList.add("on");
localStorage.removeItem('commentBarrageSwitch');
btf.snackbarShow("✨ 已开启评论弹幕", false, 2000)
}
}
if(GLOBAL_CONFIG.rightMenuEnable){
rm.hideRightMenu();
}
},
//隐藏cookie窗口
hidecookie: function() {
heo_cookiesTime = setTimeout((()=>{
document.getElementById("cookies-window").classList.add("cw-hide"),
setTimeout((()=>{
$("#cookies-window").hide()
}
), 1e3)
}
), 3e3)
},
//隐藏今日推荐
hideTodayCard: function () {
if (document.getElementById("todayCard")) {
document.getElementById("todayCard").classList.add('hide');
}
},
//更改主题色
changeThemeColor: function (color) {
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', color)
}
},
//自适应主题色
initThemeColor: function () {
if (heo.is_Post()) {
const currentTop = window.scrollY || document.documentElement.scrollTop
if (currentTop === 0) {
let themeColor = getComputedStyle(document.documentElement).getPropertyValue('--heo-main');
heo.changeThemeColor(themeColor);
} else {
let themeColor = getComputedStyle(document.documentElement).getPropertyValue('--heo-background');
heo.changeThemeColor(themeColor);
}
} else {
let themeColor = getComputedStyle(document.documentElement).getPropertyValue('--heo-background');
heo.changeThemeColor(themeColor);
}
},
//跳转到指定位置
jumpTo: function (dom) {
$(document).ready(function () {
$("html,body").animate({
scrollTop: $(dom).eq(i).offset().top
}, 500 /*scroll实现定位滚动*/); /*让整个页面可以滚动*/
});
},
//显示加载动画
showLoading: function () {
document.querySelector("#loading-box").classList.remove("loaded");
let cardColor = getComputedStyle(document.documentElement).getPropertyValue('--heo-card-bg');
heo.changeThemeColor(cardColor);
},
//隐藏加载动画
hideLoading: function () {
document.querySelector("#loading-box").classList.add("loaded");
},
//切换音乐播放状态
musicToggle: function (changePaly = true) {
const navMusicEl = document.getElementById("nav-music");
if (!heo_musicFirst) {
heo.musicBindEvent();
heo_musicFirst = true;
}
let msgPlay = '<i class="haofont hao-icon-play"></i><span>播放音乐</span>';
let msgPause = '<i class="haofont hao-icon-pause"></i><span>暂停音乐</span>';
if (heo_musicPlaying) {
navMusicEl.classList.remove("playing");
if(GLOBAL_CONFIG.rightMenuEnable){
document.getElementById("menu-music-toggle").innerHTML = msgPlay;
}
document.getElementById("nav-music-hoverTips").innerHTML = "音乐已暂停";
document.querySelector("#consoleMusic").classList.remove("on");
heo_musicPlaying = false;
navMusicEl.classList.remove("stretch");
} else {
navMusicEl.classList.add("playing");
if(GLOBAL_CONFIG.rightMenuEnable){
document.getElementById("menu-music-toggle").innerHTML = msgPause;
}
document.querySelector("#consoleMusic").classList.add("on");
heo_musicPlaying = true;
navMusicEl.classList.add("stretch");
}
if (changePaly) document.querySelector("#nav-music meting-js").aplayer.toggle();
if(GLOBAL_CONFIG.rightMenuEnable){
rm.hideRightMenu();
}
},
// 音乐绑定事件
musicBindEvent: function () {
document.querySelector("#nav-music .aplayer-music").addEventListener("click", function () {
heo.musicTelescopic();
});
document.querySelector("#nav-music .aplayer-button").addEventListener("click", function () {
heo.musicToggle(false);
});
},
// 音乐伸缩
musicTelescopic: function () {
const navMusicEl = document.getElementById("nav-music");
if (navMusicEl.classList.contains("stretch")) {
navMusicEl.classList.remove("stretch");
} else {
navMusicEl.classList.add("stretch");
}
},
//音乐上一曲
musicSkipBack: function () {
document.querySelector("meting-js").aplayer.skipBack(),
rm.hideRightMenu()
},
//音乐下一曲
musicSkipForward: function () {
document.querySelector("meting-js").aplayer.skipForward(),
rm.hideRightMenu()
},
//获取音乐中的名称
musicGetName: function () {
for (var e = $(".aplayer-title"), t = [], o = e.length - 1; o >= 0; o--)
t[o] = e[o].innerText;
return t[0]
},
// 显示打赏中控台
rewardShowConsole: function () {
$('.console-card-group-reward').attr('style', 'display: flex');
$('.console-card-group').attr('style', 'display: none');
document.querySelector("#console").classList.add("show");
heo.initConsoleState()
},
//显示中控台
showConsole: function () {
$('.console-card-group-reward').attr('style', 'display: none');
$('.console-card-group').attr('style', 'display: flex');
document.querySelector("#console").classList.add("show");
},
//隐藏中控台
hideConsole: function () {
document.querySelector("#console").classList.remove("show");
},
//快捷键功能开关
keyboardToggle: function () {
if (heo_keyboard) {
heo_keyboard = false;
document.querySelector("#consoleKeyboard").classList.remove("on");
localStorage.setItem('keyboardToggle', 'false');
} else {
heo_keyboard = true;
document.querySelector("#consoleKeyboard").classList.add("on");
localStorage.setItem('keyboardToggle', 'true');
}
},
//滚动到指定id
scrollTo: function(e) {
const t = document.getElementById(e);
if (t) {
const e = t.getBoundingClientRect().top + window.pageYOffset - 80
, o = window.pageYOffset
, n = e - o;
let a = null;
window.requestAnimationFrame((function e(t) {
a || (a = t);
const l = t - a
, i = (c = Math.min(l / 0, 1)) < .5 ? 2 * c * c : (4 - 2 * c) * c - 1;
var c;
window.scrollTo(0, o + n * i),
l < 600 && window.requestAnimationFrame(e)
}
))
}
},
//隐藏侧边栏
hideAsideBtn: () => { // Hide aside
const $htmlDom = document.documentElement.classList
$htmlDom.contains('hide-aside')
? saveToLocal.set('aside-status', 'show', 2)
: saveToLocal.set('aside-status', 'hide', 2)
$htmlDom.toggle('hide-aside')
$htmlDom.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on")
},
toPage: function() {
var e = document.querySelectorAll(".page-number")
, t = parseInt(e[e.length - 1].innerHTML)
, o = document.getElementById("toPageText")
, n = parseInt(o.value);
if (!isNaN(n) && n > 0 && "0" !== ("" + n)[0] && n <= t) {
var url = window.location.href;
var photosIndexOf = url.indexOf("?group") >= 0 ? url.indexOf("?group") : -1;
if (photosIndexOf >= 0) {//图库页面
var new_url = url.substr(0,photosIndexOf);
var group = url.substr(photosIndexOf)
var a, l = new_url.replace(/\/page\/\d$/, "");
a = 1 === n ? l : l + (l.endsWith("/") ? "" : "/") + "page/" + n,
document.getElementById("toPageButton").href = a + group
}else{
var a, l = url.replace(/\/page\/\d$/, "");
a = 1 === n ? l : l + (l.endsWith("/") ? "" : "/") + "page/" + n,
document.getElementById("toPageButton").href = a
}
//首页有第一屏就跳转指定位置
scrollToPost();
}
},
changeSayHelloText: function() {
const greetings = GLOBAL_CONFIG.helloText.length == 0 ? ["🤖️ 数码科技爱好者", "🔍 分享与热心帮助", "🏠 智能家居小能手", "🔨 设计开发一条龙", "🤝 专修交互与设计", "🏃 脚踏实地行动派", "🧱 团队小组发动机", "💢 壮汉人狠话不多"] : GLOBAL_CONFIG.helloText
, authorInfoSayHiElement = document.getElementById("author-info__sayhi");
// 如果只有一个问候语,设置为默认值
if (greetings.length === 1) {
authorInfoSayHiElement.textContent = greetings[0];
return;
}
let randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
for (; randomGreeting === lastSayHello; )
randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
authorInfoSayHiElement.textContent = randomGreeting,
lastSayHello = randomGreeting
},
//匿名评论
addRandomCommentInfo: function () {
// 从形容词数组中随机取一个值
const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)];
// 从蔬菜水果动物名字数组中随机取一个值
const randomName = vegetablesAndFruits[Math.floor(Math.random() * vegetablesAndFruits.length)];
// 将两个值组合成一个字符串
const name = `${randomAdjective}${randomName}`;
function dr_js_autofill_commentinfos() {
var lauthor = [
"#author",
"input[name='comname']",
"#inpName",
"input[name='author']",
"#ds-dialog-name",
"#name",
"input[name='nick']",
"#comment_author",
],
lmail = [
"#mail",
"#email",
"input[name='commail']",
"#inpEmail",
"input[name='email']",
"#ds-dialog-email",
"input[name='mail']",
"#comment_email",
],
lurl = [
"#url",
"input[name='comurl']",
"#inpHomePage",
"#ds-dialog-url",
"input[name='url']",
"input[name='website']",
"#website",
"input[name='link']",
"#comment_url",
];
for (var i = 0; i < lauthor.length; i++) {
var author = document.querySelector(lauthor[i]);
if (author != null) {
author.value = name;
author.dispatchEvent(new Event("input"));
author.dispatchEvent(new Event("change"));
break;
}
}
for (var j = 0; j < lmail.length; j++) {
var mail = document.querySelector(lmail[j]);
if (mail != null) {
mail.value = visitorMail;
mail.dispatchEvent(new Event("input"));
mail.dispatchEvent(new Event("change"));
break;
}
}
return !1;
}
dr_js_autofill_commentinfos();
var input = document.getElementsByClassName(GLOBAL_CONFIG.source.comments.textarea)[0];
input.focus();
input.setSelectionRange(-1, -1);
},
//爱发电赞助
addPowerLinksInPostRightSide: async function() {
const image = document.getElementById("power-star-image")
, star = document.getElementById("power-star")
, title = document.getElementById("power-star-title")
, desc = document.getElementById("power-star-desc");
if (image && star && title && desc)
try {
const list = GLOBAL_CONFIG.source.power.list
, i = heo.getRandomInt(0, list.length)
, power = list[i].realNode;
image.style.backgroundImage = `url(${power.avatar})`,
star.href = power.link,
title.innerText = power.name,
desc.innerText = power.descr
} catch (e) {}
},
getRandomInt: function(e, t) {
return Math.floor(Math.random() * (t - e)) + e
},
//初始化console图标
initConsoleState: function() {
document.documentElement.classList.contains("hide-aside") ? document.querySelector("#consoleHideAside").classList.add("on") : document.querySelector("#consoleHideAside").classList.remove("on")
},
// 音乐节目切换背景
changeMusicBg: function (isChangeBg = true) {
if (window.location.pathname != "/music") {
return;
}
const anMusicBg = document.getElementById("an_music_bg");
if (isChangeBg) {
// player listswitch 会进入此处
const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
anMusicBg.style.backgroundImage = musiccover.style.backgroundImage;
} else {
// 第一次进入,绑定事件,改背景
let timer = setInterval(() => {
const musiccover = document.querySelector("#anMusic-page .aplayer-pic");
// 确保player加载完成
if (musiccover) {
clearInterval(timer);
anMusicBg.style.backgroundImage = musiccover.style.backgroundImage;
// 绑定事件
heo.addEventListenerChangeMusicBg();
// 暂停nav的音乐
if(GLOBAL_CONFIG.navMusicEnable){
if (
document.querySelector("#nav-music meting-js").aplayer &&
!document.querySelector("#nav-music meting-js").aplayer.audio.paused
) {
heo.musicToggle();
}
}
}
}, 100);
}
},
addEventListenerChangeMusicBg: function () {
const anMusicPage = document.getElementById("anMusic-page");
const aplayerIconMenu = anMusicPage.querySelector(".aplayer-info .aplayer-time .aplayer-icon-menu");
anMusicPage.querySelector("meting-js").aplayer.on("loadeddata", function () {
heo.changeMusicBg();
console.info("player loadeddata");
});
aplayerIconMenu.addEventListener("click", function () {
$(".music-mask").css("display","block")
$(".music-mask").css("animation","0.5s ease 0s 1 normal none running to_show")
});
$(".music-mask").click(function(){
anMusicPage.querySelector(".aplayer-list").classList.remove("aplayer-list-hide");
$(".music-mask").hide();
})
},
};
const adjectives = ["美丽的", "英俊的", "聪明的", "勇敢的", "可爱的", "慷慨的", "善良的", "可靠的", "开朗的", "成熟的", "稳重的", "真诚的", "幽默的", "豁达的", "有趣的", "活泼的", "优雅的", "敏捷的", "温柔的", "温暖的", "敬业的", "细心的", "耐心的", "深沉的", "朴素的", "含蓄的", "率直的", "开放的", "务实的", "坚强的", "自信的", "谦虚的", "文静的", "深刻的", "纯真的", "朝气蓬勃的", "慎重的", "大方的", "顽强的", "迷人的", "机智的", "善解人意的", "富有想象力的", "有魅力的", "独立的", "好奇的", "干净的", "宽容的", "尊重他人的", "体贴的", "守信的", "有耐性的", "有责任心的", "有担当的", "有远见的", "有智慧的", "有眼光的", "有冒险精神的", "有爱心的", "有同情心的", "喜欢思考的", "喜欢学习的", "具有批判性思维的", "善于表达的", "善于沟通的", "善于合作的", "善于领导的", "有激情的", "有幽默感的", "有思想的", "有个性的", "有正义感的", "有责任感的", "有创造力的", "有想象力的", "有艺术细胞的", "有团队精神的", "有协调能力的", "有决策能力的", "有组织能力的", "有学习能力的", "有执行能力的", "有分析能力的", "有逻辑思维的", "有创新能力的", "有专业素养的", "有商业头脑的"]
, vegetablesAndFruits = ["萝卜", "白菜", "芹菜", "生菜", "青椒", "辣椒", "茄子", "豆角", "黄瓜", "西红柿", "洋葱", "大蒜", "土豆", "南瓜", "豆腐", "韭菜", "花菜", "西兰花", "蘑菇", "金针菇", "苹果", "香蕉", "橙子", "柠檬", "猕猴桃", "草莓", "葡萄", "桃子", "杏子", "李子", "石榴", "西瓜", "哈密瓜", "蜜瓜", "樱桃", "蓝莓", "柿子", "橄榄", "柚子", "火龙果"];
$(document).ready((function() {
initBlog()
}
)),
document.addEventListener("pjax:complete", (function() {
initBlog();
// 解决 katex pjax问题
if((GLOBAL_CONFIG.htmlType == 'post' || GLOBAL_CONFIG.htmlType == 'page') && typeof window.renderKaTex != 'undefined'){
window.renderKaTex();
}
}
));

571
templates/assets/js/main.js Normal file
View File

@ -0,0 +1,571 @@
document.addEventListener('DOMContentLoaded', function () {
const $blogName = document.getElementById('site-name')
let blogNameWidth = $blogName && $blogName.offsetWidth
const $menusEle = document.querySelector('#menus .menus_items')
let menusWidth = $menusEle && $menusEle.offsetWidth
const $searchEle = document.querySelector('#search-button')
let searchWidth = $searchEle && $searchEle.offsetWidth
const adjustMenu = (change = false) => {
if (change) {
blogNameWidth = $blogName && $blogName.offsetWidth
menusWidth = $menusEle && $menusEle.offsetWidth
searchWidth = $searchEle && $searchEle.offsetWidth
}
const $nav = document.getElementById('nav')
let t
if (window.innerWidth < 768) t = true
else t = blogNameWidth + menusWidth + searchWidth > $nav.offsetWidth - 120
if (t) {
$nav.classList.add('hide-menu')
} else {
$nav.classList.remove('hide-menu')
}
}
// 初始化header
const initAdjust = () => {
adjustMenu()
document.getElementById('nav').classList.add('show')
}
// sidebar menus
const sidebarFn = () => {
const $toggleMenu = document.getElementById('toggle-menu')
const $mobileSidebarMenus = document.getElementById('sidebar-menus')
const $menuMask = document.getElementById('menu-mask')
const $body = document.body
function openMobileSidebar() {
btf.sidebarPaddingR()
$body.style.overflow = 'hidden'
btf.fadeIn($menuMask, 0.5)
$mobileSidebarMenus.classList.add('open')
}
function closeMobileSidebar() {
$body.style.overflow = ''
$body.style.paddingRight = ''
btf.fadeOut($menuMask, 0.5)
$mobileSidebarMenus.classList.remove('open')
}
$toggleMenu.addEventListener('click', openMobileSidebar)
$menuMask.addEventListener('click', e => {
if ($mobileSidebarMenus.classList.contains('open')) {
closeMobileSidebar()
}
})
window.addEventListener('resize', e => {
if (btf.isHidden($toggleMenu)) {
if ($mobileSidebarMenus.classList.contains('open')) closeMobileSidebar()
}
})
}
/**
* 首頁top_img底下的箭頭
*/
const scrollDownInIndex = () => {
const $scrollDownEle = document.getElementById('scroll-down')
const $homeTop = document.getElementById('home_top')
$scrollDownEle && $scrollDownEle.addEventListener('click', function () {
$homeTop && btf.scrollToDest($homeTop.offsetTop, 300)
})
}
/**
* justified-gallery 圖庫排版
* 需要 jQuery
*/
let detectJgJsLoad = false
const runJustifiedGallery = function (ele) {
if (detectJgJsLoad) btf.initJustifiedGallerys(ele)
else {
$('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.justifiedGallery.css}">`)
$.getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`, function () {
btf.initJustifiedGallerys(ele)
})
detectJgJsLoad = true
}
}
/**
* fancybox
*/
const addFancybox = function (ele) {
const runFancybox = (ele) => {
ele.each(function (i, o) {
const $this = $(o)
const lazyloadSrc = $this.attr('data-lazy-src') || $this.attr('src')
const dataCaption = $this.attr('alt') || ''
$this.wrap(`<a href="${lazyloadSrc}" data-fancybox="images" data-caption="${dataCaption}" class="fancybox" data-srcset="${lazyloadSrc}"></a>`)
})
$().fancybox({
selector: '[data-fancybox]',
loop: true,
transitionEffect: 'slide',
protect: true,
buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'],
hash: false
})
}
if (typeof $.fancybox === 'undefined') {
// $('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.fancybox.css}">`)
$.getScript(`${GLOBAL_CONFIG.source.fancybox.js}`, function () {
runFancybox($(ele))
})
} else {
runFancybox($(ele))
}
}
const jqLoadAndRun = () => {
const $fancyboxEle = GLOBAL_CONFIG.lightbox === 'fancybox'
? document.querySelectorAll('#article-container :not(a):not(.rss-plan-info-group):not(.no-lightbox) > img, #article-container > img,.bber-container-img > img')
: []
const fbLengthNoZero = $fancyboxEle.length > 0
const $jgEle = document.querySelectorAll('#article-container .gallery')
const jgLengthNoZero = $jgEle.length > 0
if (jgLengthNoZero || fbLengthNoZero) {
btf.isJqueryLoad(() => {
jgLengthNoZero && runJustifiedGallery($jgEle)
fbLengthNoZero && addFancybox($fancyboxEle)
})
}
}
/**
* toc
*/
const tocFn = function () {
const postContent = document.querySelector('.post-content');
if (postContent == null) return;
const titles = postContent.querySelectorAll('h1,h2,h3,h4,h5,h6');
// 没有 toc 目录,则直接移除
if (titles.length === 0 || !titles) {
const cardToc = document.getElementById("card-toc");
cardToc?.remove();
const $mobileTocButton = document.getElementById("mobile-toc-button")
if ($mobileTocButton) {
$('#mobile-toc-button').attr('style', 'display: none');
}
} else {
tocbot.init({
tocSelector: '.toc-content',
contentSelector: '.post-content',
headingSelector: 'h1,h2,h3,h4,h5,h6',
listItemClass: 'toc-item',
activeLinkClass: 'active',
activeListItemClass: 'active',
headingsOffset: -400,
scrollSmooth: true,
scrollSmoothOffset: -70,
tocScrollOffset: 50,
});
const $cardTocLayout = document.getElementById('card-toc')
const $cardToc = $cardTocLayout.getElementsByClassName('toc-content')[0]
// toc元素點擊
$cardToc.addEventListener('click', (ele) => {
if (window.innerWidth < 900) {
$cardTocLayout.classList.remove("open");
}
})
}
}
/**
* Rightside
*/
const rightSideFn = {
switchReadMode: () => { // read-mode
const $body = document.body
$body.classList.add('read-mode')
const newEle = document.createElement('button')
newEle.type = 'button'
newEle.className = 'haofont hao-icon-sign-out-alt exit-readmode'
$body.appendChild(newEle)
function clickFn () {
$body.classList.remove('read-mode')
newEle.remove()
newEle.removeEventListener('click', clickFn)
}
newEle.addEventListener('click', clickFn)
},
showOrHideBtn: () => { // rightside 點擊設置 按鈕 展開
document.getElementById('rightside-config-hide').classList.toggle('show')
},
scrollToTop: () => { // Back to top
btf.scrollToDest(0, 500)
},
hideAsideBtn: () => { // Hide aside
const $htmlDom = document.documentElement.classList
$htmlDom.contains('hide-aside')
? saveToLocal.set('aside-status', 'show', 2)
: saveToLocal.set('aside-status', 'hide', 2)
$htmlDom.toggle('hide-aside')
},
runMobileToc: item => {
const tocEle = document.getElementById("card-toc");
tocEle.style.transformOrigin = `right ${item.getBoundingClientRect().top + 17}px`;
tocEle.style.transition = "transform 0.3s ease-in-out";
tocEle.classList.toggle("open");
tocEle.addEventListener(
"transitionend",
() => {
tocEle.style.transition = "";
tocEle.style.transformOrigin = "";
},
{ once: true }
);
},
}
document.getElementById('rightside').addEventListener('click', function (e) {
const $target = e.target.id || e.target.parentNode.id
switch ($target) {
case 'go-up':
rightSideFn.scrollToTop()
break
case 'rightside-config':
rightSideFn.showOrHideBtn()
break
case "mobile-toc-button":
rightSideFn.runMobileToc(this);
break;
case 'readmode':
rightSideFn.switchReadMode()
break
case 'darkmode':
navFn.switchDarkMode();
break
case 'hide-aside-btn':
rightSideFn.hideAsideBtn()
break
default:
break
}
})
/**
* 滾動處理
*/
const scrollFn = function () {
const $postComment = document.getElementById('post-comment')
const $rightside = document.getElementById('rightside')
const innerHeight = window.innerHeight + 0
if ($postComment) {
$('#to_comment').attr('style', 'display: block');
} else {
$('#to_comment').attr('style', 'display: none');
}
// 當滾動條小于 0 的時候
if (document.body.scrollHeight <= innerHeight) {
$rightside.style.cssText = 'opacity: 1; transform: translateX(-58px)'
return
}
let initTop = 0
let isChatShow = true
const $header = document.getElementById('page-header')
const $gulitop = document.getElementById('guli_top')
const $cookies_window = document.getElementById('cookies-window')
const isChatBtnHide = typeof chatBtnHide === 'function'
const isChatBtnShow = typeof chatBtnShow === 'function'
window.addEventListener('scroll', btf.throttle(function (e) {
const currentTop = window.scrollY || document.documentElement.scrollTop
const isDown = scrollDirection(currentTop)
if (currentTop > 0) {
if (isDown) {
if ($header.classList.contains('nav-visible')) $header.classList.remove('nav-visible')
if (isChatBtnShow && isChatShow === true) {
chatBtnHide()
isChatShow = false
}
} else {
if (!$header.classList.contains('nav-visible')) $header.classList.add('nav-visible')
if (isChatBtnHide && isChatShow === false) {
chatBtnShow()
isChatShow = true
}
}
$header.classList.add('nav-fixed')
if($cookies_window!=null && $cookies_window!=''){
$cookies_window.classList.add('cw-hide')
}
if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') {
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
}
} else {
if (currentTop === 0) {
$header.classList.remove('nav-fixed', 'nav-visible')
}
$rightside.style.cssText = "opacity: ''; transform: ''"
}
if (document.body.scrollHeight <= innerHeight) {
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
}
}, 200))
// find the scroll direction
function scrollDirection (currentTop) {
const result = currentTop > initTop // true is down & false is up
initTop = currentTop
return result
}
}
/**
* menu
* 側邊欄sub-menu 展開/收縮
* 解決menus在觸摸屏下滑動屏幕menus_item_child不消失的問題手機hover的bug)
*/
const clickFnOfSubMenu = function () {
document.querySelectorAll('#sidebar-menus .expand').forEach(function (e) {
e.addEventListener('click', function () {
this.classList.toggle('hide')
const $dom = this.parentNode.nextElementSibling
if (btf.isHidden($dom)) {
$dom.style.display = 'block'
} else {
$dom.style.display = 'none'
}
})
})
window.addEventListener('touchmove', function (e) {
const $menusChild = document.querySelectorAll('#nav .menus_item_child')
$menusChild.forEach(item => {
if (!btf.isHidden(item)) item.style.display = 'none'
})
})
}
/**
* 複製時加上版權信息
*/
const addCopyright = () => {
const copyright = GLOBAL_CONFIG.copyright
document.body.oncopy = (e) => {
e.preventDefault()
let textFont;
const copyFont = window.getSelection(0).toString()
if (copyFont.length > copyright.limitCount) {
textFont = copyFont + '\n' + '\n' + '\n' +
copyright.languages.author + '\n' +
copyright.languages.link + window.location.href + '\n' +
copyright.languages.source + '\n' +
copyright.languages.info
} else {
textFont = copyFont
}
if (e.clipboardData) {
return e.clipboardData.setData('text', textFont)
} else {
return window.clipboardData.setData('text', textFont)
}
}
}
/**
* 網頁運行時間
*/
const addRuntime = () => {
const $runtimeCount = document.getElementById('runtimeshow');
if ($runtimeCount) {
var s1 = $runtimeCount.innerText;;//建站时间
if (s1) {
s1 = new Date(s1.replace(/-/g, "/"));
s2 = new Date();
var days = s2.getTime() - s1.getTime();
var number_of_days = parseInt(days / (1000 * 60 * 60 * 24));
$runtimeCount.innerText = number_of_days + "天";
}
}
}
/**
* 最後一次更新時間
*/
const addLastPushDate = () => {
const $lastPushDateItem = document.getElementById('last-push-date')
if ($lastPushDateItem) {
const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate')
$lastPushDateItem.innerText = btf.diffDate(lastPushDate, true)
}
}
/**
* table overflow
*/
const addTableWrap = function () {
const $table = document.querySelectorAll('#article-container :not(.highlight) > table, #article-container > table')
if ($table.length) {
$table.forEach(item => {
btf.wrap(item, 'div', '', 'table-wrap')
})
}
}
/**
* tag-hide
*/
const clickFnOfTagHide = function () {
const $hideInline = document.querySelectorAll('#article-container .hide-button')
if ($hideInline.length) {
$hideInline.forEach(function (item) {
item.addEventListener('click', function (e) {
const $this = this
const $hideContent = $this.nextElementSibling
$this.classList.toggle('open')
if ($this.classList.contains('open')) {
if ($hideContent.querySelectorAll('.gallery').length > 0) {
btf.initJustifiedGallerys($hideContent.querySelectorAll('.gallery'))
}
}
})
})
}
}
const tabsFn = {
clickFnOfTabs: function () {
document.querySelectorAll('#article-container .tab > button').forEach(function (item) {
item.addEventListener('click', function (e) {
const $this = this
const $tabItem = $this.parentNode
if (!$tabItem.classList.contains('active')) {
const $tabContent = $tabItem.parentNode.nextElementSibling
const $siblings = btf.siblings($tabItem, '.active')[0]
$siblings && $siblings.classList.remove('active')
$tabItem.classList.add('active')
const tabId = $this.getAttribute('data-href').replace('#', '')
const childList = [...$tabContent.children]
childList.forEach(item => {
if (item.id === tabId) item.classList.add('active')
else item.classList.remove('active')
})
const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .gallery`)
if ($isTabJustifiedGallery.length > 0) {
btf.initJustifiedGallerys($isTabJustifiedGallery)
}
}
})
})
},
backToTop: () => {
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(function (item) {
item.addEventListener('click', function () {
btf.scrollToDest(btf.getEleTop(btf.getParents(this, '.tabs')), 300)
})
})
}
}
const toggleCardCategory = function () {
const $cardCategory = document.querySelectorAll('#aside-cat-list .card-category-list-item.parent i')
if ($cardCategory.length) {
$cardCategory.forEach(function (item) {
item.addEventListener('click', function (e) {
e.preventDefault()
const $this = this
$this.classList.toggle('expand')
const $parentEle = $this.parentNode.nextElementSibling
if (btf.isHidden($parentEle)) {
$parentEle.style.display = 'block'
} else {
$parentEle.style.display = 'none'
}
})
})
}
}
const addPostOutdateNotice = function () {
const data = GLOBAL_CONFIG.noticeOutdate
const diffDay = btf.diffDate("2022-11-04 20:08:15")
if (diffDay >= data.limitDay) {
const ele = document.createElement('div')
ele.className = 'post-outdate-notice'
ele.textContent = data.messagePrev + ' ' + diffDay + ' ' + data.messageNext
const $targetEle = document.getElementById('article-container')
if (data.position === 'top') {
$targetEle.insertBefore(ele, $targetEle.firstChild)
} else {
$targetEle.appendChild(ele)
}
}
}
const lazyloadImg = () => {
window.lazyLoadInstance = new LazyLoad({
elements_selector: 'img',
threshold: 0,
data_src: 'lazy-src',
callback_error: (img) => {
img.setAttribute("srcset", GLOBAL_CONFIG.lazyload.error);
}
})
}
const unRefreshFn = function () {
window.addEventListener('resize', adjustMenu)
window.addEventListener('orientationchange', () => {
setTimeout(adjustMenu(true), 100)
})
clickFnOfSubMenu()
GLOBAL_CONFIG.lazyload.enable && lazyloadImg()
GLOBAL_CONFIG.copyright !== undefined && addCopyright()
}
window.refreshFn = function () {
initAdjust();
if (GLOBAL_CONFIG.isPost) {
addRuntime();
tocFn();
} else {
addLastPushDate()
toggleCardCategory()
addRuntime()
}
sidebarFn()
GLOBAL_CONFIG.isHome && scrollDownInIndex()
scrollFn()
addTableWrap()
clickFnOfTagHide()
tabsFn.clickFnOfTabs()
tabsFn.backToTop()
jqLoadAndRun()
}
refreshFn()
unRefreshFn()
})

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,353 @@
var btf = {
// 修改时间显示"最近"
diffDateExact: function (d, more = false) {
const dateNow = new Date();
const datePost = new Date(d);
const dateDiff = dateNow.getTime() - datePost.getTime();
const minute = 1000 * 60;
const hour = minute * 60;
const day = hour * 24;
const month = day * 30;
let result;
if (more) {
const monthCount = dateDiff / month;
const dayCount = dateDiff / day;
const hourCount = dateDiff / hour;
const minuteCount = dateDiff / minute;
if (monthCount >= 1) {
result = datePost.toLocaleDateString().replace(/\//g, "-");
} else if (dayCount >= 1) {
result = parseInt(dayCount) + " " + GLOBAL_CONFIG.date_suffix.day;
} else if (hourCount >= 1) {
result = parseInt(hourCount) + " " + GLOBAL_CONFIG.date_suffix.hour;
} else if (minuteCount >= 1) {
result = parseInt(minuteCount) + " " + GLOBAL_CONFIG.date_suffix.min;
} else {
result = GLOBAL_CONFIG.date_suffix.just;
}
} else {
result = parseInt(dateDiff / day);
}
return result;
},
loadLightbox: ele => {
const jqLoadAndRun = () => {
const $fancyboxEle = GLOBAL_CONFIG.lightbox === 'fancybox'
? ele
: []
const fbLengthNoZero = $fancyboxEle.length > 0
if (fbLengthNoZero) {
btf.isJqueryLoad(() => {
fbLengthNoZero && addFancybox($fancyboxEle)
})
}
}
/**
* fancybox
*/
const addFancybox = function (ele) {
const runFancybox = (ele) => {
ele.each(function (i, o) {
const $this = $(o)
const lazyloadSrc = $this.attr('data-lazy-src') || $this.attr('src')
const dataCaption = $this.attr('alt') || ''
$this.wrap(`<a href="${lazyloadSrc}" data-fancybox="images" data-caption="${dataCaption}" class="fancybox" data-srcset="${lazyloadSrc}"></a>`)
})
$().fancybox({
selector: '[data-fancybox]',
loop: true,
transitionEffect: 'slide',
protect: true,
buttons: ['slideShow', 'fullScreen', 'thumbs', 'close'],
hash: false
})
}
if (typeof $.fancybox === 'undefined') {
// $('head').append(`<link rel="stylesheet" type="text/css" href="${GLOBAL_CONFIG.source.fancybox.css}">`)
$.getScript(`${GLOBAL_CONFIG.source.fancybox.js}`, function () {
runFancybox($(ele))
})
} else {
runFancybox($(ele))
}
}
jqLoadAndRun()
},
debounce: function (func, wait, immediate) {
let timeout
return function () {
const context = this
const args = arguments
const later = function () {
timeout = null
if (!immediate) func.apply(context, args)
}
const callNow = immediate && !timeout
clearTimeout(timeout)
timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args)
}
},
throttle: function (func, wait, options) {
let timeout, context, args
let previous = 0
if (!options) options = {}
const later = function () {
previous = options.leading === false ? 0 : new Date().getTime()
timeout = null
func.apply(context, args)
if (!timeout) context = args = null
}
const throttled = function () {
const now = new Date().getTime()
if (!previous && options.leading === false) previous = now
const remaining = wait - (now - previous)
context = this
args = arguments
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout)
timeout = null
}
previous = now
func.apply(context, args)
if (!timeout) context = args = null
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining)
}
}
return throttled
},
sidebarPaddingR: () => {
const innerWidth = window.innerWidth
const clientWidth = document.body.clientWidth
const paddingRight = innerWidth - clientWidth
if (innerWidth !== clientWidth) {
document.body.style.paddingRight = paddingRight + 'px'
}
},
snackbarShow: (text, showActionFunction = false, duration = 2000, actionText = false) => {
const { position, bgLight, bgDark } = GLOBAL_CONFIG.Snackbar;
const bg = document.documentElement.getAttribute("data-theme") === "light" ? bgLight : bgDark;
const root = document.querySelector(":root");
root.style.setProperty("--heo-snackbar-time", duration + "ms");
Snackbar.show({
text: text,
backgroundColor: bg,
onActionClick: showActionFunction,
actionText: actionText,
showAction: actionText,
duration: duration,
pos: position,
customClass: "snackbar-css",
});
},
initJustifiedGallerys: function (selector) {
selector.forEach((function(t) {
btf.isHidden(t) || fjGallery(t, {
itemSelector: ".fj-gallery-item",
rowHeight: 240,
gutter: 4,
onJustify: function() {
this.$container.style.opacity = "1"
}
})
}
))
document.querySelectorAll('#article-container .loadings')[0]?.classList.remove("loadings");
},
diffDate: (d, more = false) => {
const dateNow = new Date()
const datePost = new Date(d)
const dateDiff = dateNow.getTime() - datePost.getTime()
const minute = 1000 * 60
const hour = minute * 60
const day = hour * 24
const month = day * 30
let result
if (more) {
const monthCount = dateDiff / month
const dayCount = dateDiff / day
const hourCount = dateDiff / hour
const minuteCount = dateDiff / minute
if (monthCount > 12) {
// result = datePost.toLocaleDateString().replace(/\//g, '-')
result = datePost.toLocaleDateString()
} else if (dayCount >= 7) {
// } else if (monthCount >= 1) {
result = datePost.toLocaleDateString().substr(5)
// result = parseInt(monthCount) + ' ' + GLOBAL_CONFIG.date_suffix.month
} else if (dayCount >= 1) {
result = parseInt(dayCount) + '' + GLOBAL_CONFIG.date_suffix.day
} else if (hourCount >= 1) {
// result = '最近'
result = parseInt(hourCount) + ' ' + GLOBAL_CONFIG.date_suffix.hour
} else if (minuteCount >= 1) {
// result = '最近'
result = parseInt(minuteCount) + ' ' + GLOBAL_CONFIG.date_suffix.min
} else {
result = GLOBAL_CONFIG.date_suffix.just
}
} else {
result = parseInt(dateDiff / day)
}
return result
},
loadComment: (dom, callback) => {
if ('IntersectionObserver' in window) {
const observerItem = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
callback()
observerItem.disconnect()
}
}, {threshold: [0]})
observerItem.observe(dom)
} else {
callback()
}
},
scrollToDest: (e,t)=>{
if (e < 0 || t < 0)
return;
const n = window.scrollY || window.screenTop;
if (e -= 70,
"CSS"in window && CSS.supports("scroll-behavior", "smooth"))
return void window.scrollTo({
top: e,
behavior: "smooth"
});
let o = null;
t = t || 500,
window.requestAnimationFrame((function i(s) {
if (o = o || s,
n < e) {
const r = s - o;
window.scrollTo(0, (e - n) * r / t + n),
r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e)
} else {
const r = s - o;
window.scrollTo(0, n - (n - e) * r / t),
r < t ? window.requestAnimationFrame(i) : window.scrollTo(0, e)
}
}
))
},
fadeIn: (ele, time) => {
ele.style.cssText = `display:block;animation: to_show ${time}s`
},
fadeOut: (ele, time) => {
ele.addEventListener('animationend', function f() {
ele.style.cssText = "display: none; animation: '' "
ele.removeEventListener('animationend', f)
})
ele.style.animation = `to_hide ${time}s`
},
getParents: (elem, selector) => {
for (; elem && elem !== document; elem = elem.parentNode) {
if (elem.matches(selector)) return elem
}
return null
},
siblings: (ele, selector) => {
return [...ele.parentNode.children].filter((child) => {
if (selector) {
return child !== ele && child.matches(selector)
}
return child !== ele
})
},
/**
*
* @param {*} selector
* @param {*} eleType the type of create element
* @param {*} id id
* @param {*} cn class name
*/
wrap: function (selector, eleType, id = '', cn = '') {
const creatEle = document.createElement(eleType)
if (id) creatEle.id = id
if (cn) creatEle.className = cn
selector.parentNode.insertBefore(creatEle, selector)
creatEle.appendChild(selector)
},
unwrap: function (el) {
const elParentNode = el.parentNode
if (elParentNode !== document.body) {
elParentNode.parentNode.insertBefore(el, elParentNode)
elParentNode.parentNode.removeChild(elParentNode)
}
},
isJqueryLoad: (fn) => {
if (typeof jQuery === 'undefined') {
getScript(GLOBAL_CONFIG.source.jQuery).then(fn)
} else {
fn()
}
},
isHidden: (ele) => ele.offsetHeight === 0 && ele.offsetWidth === 0,
getEleTop: (ele) => {
let actualTop = ele.offsetTop
let current = ele.offsetParent
while (current !== null) {
actualTop += current.offsetTop
current = current.offsetParent
}
return actualTop
},
//过滤标签
changeContent: (content,length = null)=>{
if (content === '') return content
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
content = content.replace(/<[^>]+>/g, "") // remove html tag
if (length!=null){
if (content.length > length) {
content = content.substring(0, length) + '...'
}
}
return content
}
}

BIN
templates/assets/libs/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
"use strict";function _objectSpread(a){for(var b=1;b<arguments.length;b++){var c=null==arguments[b]?{}:arguments[b],d=Object.keys(c);"function"==typeof Object.getOwnPropertySymbols&&(d=d.concat(Object.getOwnPropertySymbols(c).filter(function(a){return Object.getOwnPropertyDescriptor(c,a).enumerable}))),d.forEach(function(b){_defineProperty(a,b,c[b])})}return a}function _defineProperty(a,b,c){return b in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}class MetingJSElement extends HTMLElement{connectedCallback(){window.APlayer&&window.fetch&&(this._init(),this._parse())}disconnectedCallback(){this.lock||this.aplayer.destroy()}_camelize(a){return a.replace(/^[_.\- ]+/,"").toLowerCase().replace(/[_.\- ]+(\w|$)/g,(a,b)=>b.toUpperCase())}_init(){let a={};for(let b=0;b<this.attributes.length;b+=1)a[this._camelize(this.attributes[b].name)]=this.attributes[b].value;let b=["server","type","id","api","auth","auto","lock","name","title","artist","author","url","cover","pic","lyric","lrc"];this.meta={};for(var c=0;c<b.length;c++){let d=b[c];this.meta[d]=a[d],delete a[d]}this.config=a,this.api=this.meta.api||window.meting_api||"https://api.i-meto.com/meting/api?server=:server&type=:type&id=:id&r=:r",this.meta.auto&&this._parse_link()}_parse_link(){let a=[["music.163.com.*song.*id=(\\d+)","netease","song"],["music.163.com.*album.*id=(\\d+)","netease","album"],["music.163.com.*artist.*id=(\\d+)","netease","artist"],["music.163.com.*playlist.*id=(\\d+)","netease","playlist"],["music.163.com.*discover/toplist.*id=(\\d+)","netease","playlist"],["y.qq.com.*song/(\\w+).html","tencent","song"],["y.qq.com.*album/(\\w+).html","tencent","album"],["y.qq.com.*singer/(\\w+).html","tencent","artist"],["y.qq.com.*playsquare/(\\w+).html","tencent","playlist"],["y.qq.com.*playlist/(\\w+).html","tencent","playlist"],["xiami.com.*song/(\\w+)","xiami","song"],["xiami.com.*album/(\\w+)","xiami","album"],["xiami.com.*artist/(\\w+)","xiami","artist"],["xiami.com.*collect/(\\w+)","xiami","playlist"]];for(var b=0;b<a.length;b++){let c=a[b],d=new RegExp(c[0]),e=d.exec(this.meta.auto);if(null!==e)return this.meta.server=c[1],this.meta.type=c[2],void(this.meta.id=e[1])}}_parse(){if(this.meta.url){let a={name:this.meta.name||this.meta.title||"Audio name",artist:this.meta.artist||this.meta.author||"Audio artist",url:this.meta.url,cover:this.meta.cover||this.meta.pic,lrc:this.meta.lrc||this.meta.lyric||"",type:this.meta.type||"auto"};return a.lrc||(this.meta.lrcType=0),this.innerText&&(a.lrc=this.innerText,this.meta.lrcType=2),void this._loadPlayer([a])}let a=this.api.replace(":server",this.meta.server).replace(":type",this.meta.type).replace(":id",this.meta.id).replace(":auth",this.meta.auth).replace(":r",Math.random());fetch(a).then(a=>a.json()).then(a=>this._loadPlayer(a))}_loadPlayer(a){let b={audio:a,mutex:!0,lrcType:this.meta.lrcType||3,storageName:"metingjs"};if(a.length){let a=_objectSpread({},b,this.config);for(let b in a)("true"===a[b]||"false"===a[b])&&(a[b]="true"===a[b]);let c=document.createElement("div");a.container=c,this.appendChild(c),this.aplayer=new APlayer(a)}}}window.customElements&&!window.customElements.get("meting-js")&&(window.MetingJSElement=MetingJSElement,window.customElements.define("meting-js",MetingJSElement));

View File

@ -0,0 +1,595 @@
#an_music_bg {
display: none;
filter: blur(63px);
opacity: .6;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
filter: alpha(opacity=60);
position: fixed;
z-index: -999;
background-attachment: local;
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
-webkit-transform: rotate(0);
-moz-transform: rotate(0);
-o-transform: rotate(0);
-ms-transform: rotate(0);
transform: rotate(0);
-webkit-transition: .3s;
-moz-transition: .3s;
-o-transition: .3s;
-ms-transition: .3s;
transition: .3s
}
body {
background: #0d0d0d;
}
#an_music_bg {
display: block;
}
body[data-type=music] .music-mask{
display: none;
}
body[data-type=music] #rightside{
display: none;
}
body[data-type=music] #web_bg {
display: none;
}
body[data-type=music] #page {
min-height: calc(0px)
}
@media screen and (max-width: 768px) {
body[data-type=music] .page .layout#content-inner {
background: 0 0!important;
}
body[data-type=music] #page-header.not-top-img:not(.nav-fixed) #nav{
background: 0 0!important;
}
}
#page-header.not-top-img #nav .back-home-button,
#page-header.not-top-img #nav a {
color:#F7F7FA;
}
#page-header.not-top-img #nav .back-home-button:hover{
color: var(--heo-card-bg);
}
body[data-type=music] #footer,
body[data-type=music] #nav-music {
display: none;
}
#anMusic-page .aplayer-body {
width: 40%;
height: 75vh;
}
#anMusic-page ol>li:hover {
background: #ffffff33;
border-radius: 6px;
}
@media screen and (max-width: 1400px) {
body #anMusic-page #anMusicBtnGetSong,
body #anMusic-page #anMusicRefreshBtn,
body #anMusic-page #anMusicSwitching {
right: 7vw
}
body #anMusic-page #anMusicSwitching {
bottom: 100px
}
body #anMusic-page #anMusicRefreshBtn {
bottom: 160px
}
body #anMusic-page #anMusicBtnGetSong {
bottom: 220px
}
}
#anMusic-page #anMusicBtnGetSong,
#anMusic-page #anMusicRefreshBtn,
#anMusic-page #anMusicSwitching {
position: fixed;
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
width: 50px;
height: 50px;
bottom: 100px;
padding: 5px;
background: var(--heo-white-op);
backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 50%;
color: #fff;
text-align: center;
-webkit-box-pack: center;
-moz-box-pack: center;
-o-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-moz-box-align: center;
-o-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
cursor: pointer;
z-index: 2
}
#anMusic-page #anMusicBtnGetSong {
right: 11vw
}
#anMusic-page #anMusicRefreshBtn {
right: 7vw
}
#anMusic-page #anMusicSwitching {
right: 15vw
}
@media screen and (max-width: 768px) {
#anMusic-page div#anMusicBtnGetSong {
right: 80px;
bottom: 150px
}
#anMusic-page div#anMusicRefreshBtn {
right: 20px;
bottom: 150px
}
#anMusic-page div#anMusicSwitching {
right: 140px;
bottom: 150px
}
}
#anMusic-page meting-js .aplayer {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
-webkit-box-direction: reverse;
-moz-box-direction: reverse;
-o-box-direction: reverse;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
-o-box-orient: horizontal;
-webkit-flex-direction: row-reverse;
-ms-flex-direction: row-reverse;
flex-direction: row-reverse;
background: rgba(0, 0, 0, 0);
border: none;
-webkit-box-shadow: none;
box-shadow: none
}
#anMusic-page meting-js .aplayer .aplayer-body {
width: 40%;
height: calc(100vh - 169px)
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-pic {
float: none;
width: 180px;
height: 180px;
border-radius: 12px;
margin: auto;
left: 0;
right: 0;
-webkit-transition: background-image .5s ease-in-out;
-moz-transition: background-image .5s ease-in-out;
-o-transition: background-image .5s ease-in-out;
-ms-transition: background-image .5s ease-in-out;
transition: background-image .5s ease-in-out;
background-size: cover;
background-color: transparent !important
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info {
margin: 0 20px 0 20px;
border-bottom: none
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-music {
text-align: center;
height: auto;
margin: 15px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-music .aplayer-author,
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-music .aplayer-title {
font-size: 1.7rem;
font-weight: 700;
color: #fff
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc {
height: 800%;
margin-top: 10px;
mask-image: linear-gradient(to bottom, #000, #000, #000, #000, #000, #000, #000, #000, #000, #000, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0))
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc p {
font-size: 20px;
line-height: 20px !important;
height: 20px !important;
margin: 20px 0 !important;
color: #fff
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc p.aplayer-lrc-current {
min-height: 20px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc::after,
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc::before {
display: none
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller {
position: fixed;
max-width: 1500px;
margin: auto;
left: 0;
right: 0;
bottom: 50px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap {
margin: 0 160px 0 150px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar {
height: 6px;
border-radius: 4px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played {
height: 6px;
border-radius: 4px;
background: var(--heo-white) !important
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb {
width: 20px;
height: 20px;
margin-top: -7px;
-webkit-transform: none;
-moz-transform: none;
-o-transform: none;
-ms-transform: none;
transform: none;
background: #fff !important
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded {
height: 6px;
border-radius: 4px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time {
position: absolute;
width: 100%;
bottom: 21px;
height: 0;
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
-webkit-box-pack: end;
-moz-box-pack: end;
-o-box-pack: end;
-ms-flex-pack: end;
-webkit-justify-content: flex-end;
justify-content: flex-end
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-volume-wrap .aplayer-volume-bar-wrap {
bottom: 0;
right: -5px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon {
width: 2rem;
height: 1.6rem;
margin-left: 6px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path {
fill: var(--heo-white);
opacity: .8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80)
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon.aplayer-icon-loop {
margin-right: 15px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-time-inner {
margin-right: 18px;
margin-top: -8px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-back {
position: absolute;
left: 0;
display: inline
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-play {
position: absolute;
left: 40px;
display: inline
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-forward {
position: absolute;
left: 80px;
display: inline
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-menu {
display: none
}
#anMusic-page meting-js .aplayer .aplayer-list {
width: 60%;
height: 100%
}
#anMusic-page meting-js .aplayer ol {
padding-right: 25px
}
#anMusic-page meting-js .aplayer ol>li {
border-top: 1px solid transparent;
font-size: 14px
}
#anMusic-page meting-js .aplayer ol>li:hover {
background: rgba(255, 255, 255, .2);
border-radius: 6px
}
#anMusic-page meting-js .aplayer ol>li.aplayer-list-light {
background: rgba(255, 255, 255, .2);
border-radius: 6px;
padding: 20px 15px
}
#anMusic-page meting-js .aplayer ol>li.aplayer-list-light span.aplayer-list-title {
font-weight: bolder
}
#anMusic-page meting-js .aplayer ol>li.aplayer-list-light .aplayer-list-cur {
display: none
}
#anMusic-page meting-js .aplayer ol>li span {
color: var(--heo-white)
}
#anMusic-page meting-js .aplayer ol>li span.aplayer-list-author {
opacity: .6;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
filter: alpha(opacity=60)
}
@media screen and (max-width: 768px) {
body[data-type=music] #content-inner,
body[data-type=music] #page {
z-index: auto
}
#anMusic-page meting-js .aplayer .aplayer-list {
position: fixed;
z-index: 100;
width: 100%;
bottom: -88%;
left: 0;
background: var(--sidebar-bg);
height: auto;
border-radius: 15px 15px 0 0;
padding: 15px 0
}
#anMusic-page meting-js .aplayer .aplayer-list.aplayer-list-hide {
bottom: 0 !important
}
#anMusic-page meting-js .aplayer .aplayer-list ol {
max-height: 60vh !important;
padding-right: 0
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
margin: 0 10px
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li span {
color: var(--font-color)
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li span.aplayer-list-title {
width: 30%;
max-width: 55%;
width: auto;
display: -webkit-box;
-webkit-line-clamp: 1;
overflow: hidden;
-webkit-box-orient: vertical
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li span.aplayer-list-author {
position: absolute;
right: 10px;
width: auto;
max-width: 35%;
display: -webkit-box;
-webkit-line-clamp: 1;
overflow: hidden;
-webkit-box-orient: vertical
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li.aplayer-list-light {
background: #33a673;
padding: 5px 20px;
border-radius: 10px
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li.aplayer-list-light span {
color: #fff
}
#anMusic-page meting-js .aplayer .aplayer-list ol>li.aplayer-list-light span.aplayer-list-author {
right: 15px
}
#anMusic-page meting-js .aplayer .aplayer-body {
width: 100%;
position: fixed;
margin: auto;
left: 0;
right: 0;
top: 100px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc {
margin-top: 40px;
height: auto;
max-height: 200%;
min-height: 100%;
mask-image: linear-gradient(to bottom, #000, #000, #000, #000, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0))
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-lrc p.aplayer-lrc-current {
color: #33a673
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller {
width: 100%;
bottom: 100px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-volume-wrap {
left: -66px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-volume-wrap .aplayer-volume-bar-wrap {
bottom: 0;
right: 7px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-bar-wrap {
margin: 0 30px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time {
bottom: -40px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-time-inner {
position: absolute;
width: 100%;
margin-right: 0;
margin-top: -33px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-time-inner .aplayer-dtime {
position: absolute;
right: 30px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-time-inner .aplayer-ptime {
position: absolute;
left: 35px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-back {
margin: auto;
right: 110px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-play {
margin: auto;
right: 0;
left: 0
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-forward {
margin: auto;
left: 110px;
right: 0
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-order {
position: absolute;
left: 22px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-loop {
position: absolute;
right: 10px
}
#anMusic-page meting-js .aplayer .aplayer-body .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon-menu {
display: inline;
position: absolute;
right: 25px;
top: -90px
}
body[data-type=music] .music-mask{
position: fixed;
z-index: 10;
display: none;
width: 100%;
height: 100%;
background: var(--heo-maskbg);
backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: blur(20px);
transform: translateZ(0);
animation: 0.6s ease 0s 1 normal none running to_show;
left: 0;
top: 0;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
if(document.querySelector(".author-content.author-content-item.single")){const canvas=document.createElement("canvas");canvas.id="header_canvas",canvas.style.position="absolute",canvas.style.bottom="0",canvas.width=844,canvas.height=346,document.querySelector(".author-content.author-content-item.single").appendChild(canvas);document.querySelector(".author-content.author-content-item.single").parentNode.className="thumbnail_canvas",function(){var canvas,ctx,width,height,bubbles;function animate(){for(var i in ctx.clearRect(0,0,width,height),bubbles)bubbles[i].draw();requestAnimationFrame(animate)}function window_resize(){const panel=document.querySelector(".thumbnail_canvas");panel&&(width=panel.offsetWidth,height=panel.offsetHeight,canvas.width=width,canvas.height=height)}function Bubble(){var _this=this;function init(){_this.pos.x=Math.random()*width,_this.pos.y=height+100*Math.random(),_this.alpha=.1+.5*Math.random(),_this.alpha_change=2e-4+5e-4*Math.random(),_this.scale=.2+.8*Math.random(),_this.scale_change=.002*Math.random(),_this.speed=.1+.4*Math.random()}_this.pos={},init(),this.draw=function(){_this.alpha<=0&&init(),_this.pos.y-=_this.speed,_this.alpha-=_this.alpha_change,_this.scale+=_this.scale_change,ctx.beginPath(),ctx.arc(_this.pos.x,_this.pos.y,10*_this.scale,0,2*Math.PI,!1),ctx.fillStyle="rgba(255,255,255,"+_this.alpha+")",ctx.fill()}}!function(){if(canvas=document.getElementById("header_canvas"),window_resize(),canvas){ctx=canvas.getContext("2d"),bubbles=[];for(var num=.04*width,i=0;i<num;i++){var c=new Bubble;bubbles.push(c)}animate()}}(),window.onresize=function(){window_resize()}}()}

View File

@ -0,0 +1 @@
function dark(){window.requestAnimationFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;var n,e,i,h,t=.05,s=document.getElementById("universe"),o=!0,d="226,225,224",c=[];function f(){n=window.innerWidth,e=window.innerHeight,i=.216*n,s.setAttribute("width",n),s.setAttribute("height",e)}function u(){h.clearRect(0,0,n,e);for(var t=c.length,i=0;i<t;i++){var s=c[i];s.move(),s.fadeIn(),s.fadeOut(),s.draw()}}function y(){this.reset=function(){this.giant=m(3),this.comet=!this.giant&&!o&&m(10),this.x=l(0,n-10),this.y=l(0,e),this.r=l(1.1,2.6),this.dx=l(t,6*t)+(this.comet+1-1)*t*l(50,120)+.1,this.dy=-l(t,6*t)-(this.comet+1-1)*t*l(50,120),this.fadingOut=null,this.fadingIn=!0,this.opacity=0,this.opacityTresh=l(.2,1-.4*(this.comet+1-1)),this.do=l(5e-4,.002)+.001*(this.comet+1-1)},this.fadeIn=function(){this.fadingIn&&(this.fadingIn=!(this.opacity>this.opacityTresh),this.opacity+=this.do)},this.fadeOut=function(){this.fadingOut&&(this.fadingOut=!(this.opacity<0),this.opacity-=this.do/2,(this.x>n||this.y<0)&&(this.fadingOut=!1,this.reset()))},this.draw=function(){if(h.beginPath(),this.giant)h.fillStyle="rgba(180,184,240,"+this.opacity+")",h.arc(this.x,this.y,2,0,2*Math.PI,!1);else if(this.comet){h.fillStyle="rgba("+d+","+this.opacity+")",h.arc(this.x,this.y,1.5,0,2*Math.PI,!1);for(var t=0;t<30;t++)h.fillStyle="rgba("+d+","+(this.opacity-this.opacity/20*t)+")",h.rect(this.x-this.dx/4*t,this.y-this.dy/4*t-2,2,2),h.fill()}else h.fillStyle="rgba(226,225,142,"+this.opacity+")",h.rect(this.x,this.y,this.r,this.r);h.closePath(),h.fill()},this.move=function(){this.x+=this.dx,this.y+=this.dy,!1===this.fadingOut&&this.reset(),(this.x>n-n/4||this.y<0)&&(this.fadingOut=!0)},setTimeout((function(){o=!1}),50)}function m(t){return Math.floor(1e3*Math.random())+1<10*t}function l(t,i){return Math.random()*(i-t)+t}f(),window.addEventListener("resize",f,!1),function(){h=s.getContext("2d");for(var t=0;t<i;t++)c[t]=new y,c[t].reset();u()}(),function t(){"dark"==document.getElementsByTagName("html")[0].getAttribute("data-theme")&&u(),window.requestAnimationFrame(t)}()}dark();

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
var CountUp=function(target,startVal,endVal,decimals,duration,options){var self=this;self.version=function(){return"1.9.2"};self.options={useEasing:true,useGrouping:true,separator:",",decimal:".",easingFn:easeOutExpo,formattingFn:formatNumber,prefix:"",suffix:"",numerals:[]};if(options&&typeof options==="object"){for(var key in self.options){if(options.hasOwnProperty(key)&&options[key]!==null){self.options[key]=options[key]}}}if(self.options.separator===""){self.options.useGrouping=false}else{self.options.separator=""+self.options.separator}var lastTime=0;var vendors=["webkit","moz","ms","o"];for(var x=0;x<vendors.length&&!window.requestAnimationFrame;++x){window.requestAnimationFrame=window[vendors[x]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[vendors[x]+"CancelAnimationFrame"]||window[vendors[x]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(callback,element){var currTime=new Date().getTime();var timeToCall=Math.max(0,16-(currTime-lastTime));var id=window.setTimeout(function(){callback(currTime+timeToCall)},timeToCall);lastTime=currTime+timeToCall;return id}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(id){clearTimeout(id)}}function formatNumber(num){num=num.toFixed(self.decimals);num+="";var x,x1,x2,x3,i,l;x=num.split(".");x1=x[0];x2=x.length>1?self.options.decimal+x[1]:"";if(self.options.useGrouping){x3="";for(i=0,l=x1.length;i<l;++i){if(i!==0&&((i%3)===0)){x3=self.options.separator+x3}x3=x1[l-i-1]+x3}x1=x3}if(self.options.numerals.length){x1=x1.replace(/[0-9]/g,function(w){return self.options.numerals[+w]});x2=x2.replace(/[0-9]/g,function(w){return self.options.numerals[+w]})}return self.options.prefix+x1+x2+self.options.suffix}function easeOutExpo(t,b,c,d){return c*(-Math.pow(2,-10*t/d)+1)*1024/1023+b}function ensureNumber(n){return(typeof n==="number"&&!isNaN(n))}self.initialize=function(){if(self.initialized){return true}self.error="";self.d=(typeof target==="string")?document.getElementById(target):target;if(!self.d){self.error="[CountUp] target is null or undefined";return false}self.startVal=Number(startVal);self.endVal=Number(endVal);if(ensureNumber(self.startVal)&&ensureNumber(self.endVal)){self.decimals=Math.max(0,decimals||0);self.dec=Math.pow(10,self.decimals);self.duration=Number(duration)*1000||2000;self.countDown=(self.startVal>self.endVal);self.frameVal=self.startVal;self.initialized=true;return true}else{self.error="[CountUp] startVal ("+startVal+") or endVal ("+endVal+") is not a number";return false}};self.printValue=function(value){var result=self.options.formattingFn(value);if(self.d.tagName==="INPUT"){this.d.value=result}else{if(self.d.tagName==="text"||self.d.tagName==="tspan"){this.d.textContent=result}else{this.d.innerHTML=result}}};self.count=function(timestamp){if(!self.startTime){self.startTime=timestamp}self.timestamp=timestamp;var progress=timestamp-self.startTime;self.remaining=self.duration-progress;if(self.options.useEasing){if(self.countDown){self.frameVal=self.startVal-self.options.easingFn(progress,0,self.startVal-self.endVal,self.duration)}else{self.frameVal=self.options.easingFn(progress,self.startVal,self.endVal-self.startVal,self.duration)}}else{if(self.countDown){self.frameVal=self.startVal-((self.startVal-self.endVal)*(progress/self.duration))}else{self.frameVal=self.startVal+(self.endVal-self.startVal)*(progress/self.duration)}}if(self.countDown){self.frameVal=(self.frameVal<self.endVal)?self.endVal:self.frameVal}else{self.frameVal=(self.frameVal>self.endVal)?self.endVal:self.frameVal}self.frameVal=Math.round(self.frameVal*self.dec)/self.dec;self.printValue(self.frameVal);if(progress<self.duration){self.rAF=requestAnimationFrame(self.count)}else{if(self.callback){self.callback()}}};self.start=function(callback){if(!self.initialize()){return}self.callback=callback;self.rAF=requestAnimationFrame(self.count)};self.pauseResume=function(){if(!self.paused){self.paused=true;cancelAnimationFrame(self.rAF)}else{self.paused=false;delete self.startTime;self.duration=self.remaining;self.startVal=self.frameVal;requestAnimationFrame(self.count)}};self.reset=function(){self.paused=false;delete self.startTime;self.initialized=false;if(self.initialize()){cancelAnimationFrame(self.rAF);self.printValue(self.startVal)}};self.update=function(newEndVal){if(!self.initialize()){return}newEndVal=Number(newEndVal);if(!ensureNumber(newEndVal)){self.error="[CountUp] update() - new endVal is not a number: "+newEndVal;return}self.error="";if(newEndVal===self.frameVal){return}cancelAnimationFrame(self.rAF);self.paused=false;delete self.startTime;self.startVal=self.frameVal;self.endVal=newEndVal;self.countDown=(self.startVal>self.endVal);self.rAF=requestAnimationFrame(self.count)};if(self.initialize()){self.printValue(self.startVal)}};

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="renderer" content="webkit" />
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, shrink-to-fit=no, viewport-fit=cover" />
<title>DPlayer</title>
<style>
* {
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
outline: none;
text-decoration: none;
}
html,
body,
#dplayer {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="dplayer"></div>
<script src="/themes/theme-hao/assets/libs/hls/hls.min.js"></script>
<script src="/themes/theme-hao/assets/libs/dplayer/DPlayer.min.js"></script>
<script>
var getUrlParams = function (key) {
var search = location.search;
// 判断是否为字符串类型
if (typeof search !== "string") {
search = search.toString();
}
var paramsSplit = search.replace(/^[^\?]*\?/i, "").split(/&/);
var params = {};
// 数据为空
if (paramsSplit.length < 1) {
return params;
}
if (Array.isArray(paramsSplit)) {
paramsSplit.forEach(function (item) {
// 数据为空, 退出方法
if (!item) {
return false;
}
var itemSplit = item.split(/=/);
// 判断字符串中是否有多个=
if (itemSplit.length >= 2) {
// 是
var key = itemSplit.splice(0, 1);
params[key] = itemSplit.join("=");
}
});
}
return key ? params[key] : params;
}
new DPlayer({
container: document.getElementById('dplayer'), // 播放器容器元素
autoplay: false, // 视频自动播放
theme: '#409eff', // 主题色
loop: false, // 视频循环播放
screenshot: false, // 开启截图,如果开启,视频和视频封面需要允许跨域
airplay: true, // 在 Safari 中开启 AirPlay
volume: 0.5, // 默认音量,请注意播放器会记忆用户设置,用户手动设置音量后默认音量即失效
playbackSpeed: [2, 1.5, 1.25, 1], // 可选的播放速率,可以设置成自定义的数组
video: {
url: getUrlParams('url')
}
})
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,512 @@
@charset "utf-8";
/*
Last Modified time : 20220211 98:00 by https://immmmm.com
已适配 FriendCircle 公共库和主库
*/
:root {
--lmm-fontcolor: #363636;
--lmm-background: #f7f9fe;
--lmm-floorcolor: #a9a9b3;
--lmm-dark-fontcolor: #a9a9b3;
--lmm-dack-background: #252627;
--lmm-dark-floorcolor: #454545;
}
[data-theme=light] {
--lmm-fontcolor: #363636;
--lmm-background: #f7f9fe;
--lmm-floorcolor: #a9a9b3;
}
[data-theme=dark] {
--lmm-fontcolor: #a9a9b3;
--lmm-background: #252627;
--lmm-floorcolor: #454545;
}
/* 基本信息 */
#cf-state {
font-size: 16px;
border-radius: 8px;
box-shadow: none;
max-width: 810px;
margin: auto;
overflow: hidden;
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 8px 0;
}
.cf-state-data {
width: 100%;
display: flex;
}
.cf-data-friends, .cf-data-active, .cf-data-article {
height: 60px;
background: transparent;
display: flex;
flex-direction: column;
width: 33%;
cursor: pointer;
}
.cf-label {
font-size: 16px;
padding: 0 3%;
align-self: center;
text-align: center;
width: 100%;
height: 30px;
}
.cf-message {
align-self: center;
text-align: center;
padding: 0 3%;
width: 50%;
font-size: 20px;
}
/* 排序按钮 */
#cf-change {
font-size: 14px;
display: block;
padding: 12px 0 4px;
width: 100%;
text-align: center;
}
/* 更多按钮 */
#cf-more {
width: 40%;
max-width: 810px;
height: 30px;
margin: auto;
margin-top: 1rem;
border-radius: 12px;
font-weight: bolder;
text-align: center;
display: flex;
flex-direction: column;
justify-content: space-around;
cursor: pointer;
transition: 0.3s;
}
#cf-more:hover {
width: 60%;
background: var(--heo-main);
color: var(--heo-white);
border: var(--style-border-hover);
box-shadow: var(--heo-shadow-main);
}
#cf-more i.fas::before {
content: "∞";
}
/* 主容器 */
#cf-container {
width: 100%;
max-width: 1500px;
height: auto;
margin: auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
#cf-container a {
text-decoration: none;
display: flex;
align-items: center;
border-bottom: none;
}
#cf-container a:hover {
color: var(--heo-lighttext) !important;
border-bottom: none !important;
background-color: var(--heo-none) !important;
box-shadow: none !important;
}
#cf-container .img-alt {
display: none;
}
.cf-article-avatar {
line-height: 35px;
display: flex;
justify-content: space-between;
}
.cf-img-avatar {
align-self: center;
text-align: center;
width: 22px !important;
height: 22px !important;
min-width: 22px !important;
min-height: 22px !important;
border-radius: 50%;
background: #fff;
margin-right: 0.3rem;
}
img.cf-img-avatar {
margin-bottom: 0 !important;
margin-top: 0 !important;
}
.cf-article-author {
line-height: 35px;
font-size: 14px;
font-weight: 400;
margin-left: 5px;
align-self: center;
text-align: center;
white-space: nowrap;
overflow: hidden;
transition: 0.3s;
}
.cf-article-avatar a:hover span {
color: var(--heo-lighttext);
}
.cf-article-author:hover {
color: var(--heo-lighttext);
}
.cf-article-author .cf-img-avatar {
margin-right: 0.3rem;
}
.cf-article-floor {
position: absolute;
top: 0;
right: 0.5rem;
font-style: italic;
font-size: 3rem;
line-height: 1.5rem;
z-index: 1;
font-weight: 400;
display: none;
}
.cf-article-title {
font-weight: 500;
position: relative;
z-index: 2;
margin-right: auto;
display: block;
letter-spacing: 1.5px;
font-size: 18px;
align-self: start;
text-align: left;
line-height: 1.2;
padding: 0;
margin-bottom: 10px;
transition: 0.3s;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box !important;
-webkit-box-orient: vertical;
}
.cf-article-time {
font-size: 14px;
text-align: right;
float: right;
font-weight: 400;
}
.cf-time-updated, .cf-time-created {
display: inline-block;
text-align: left;
white-space: nowrap;
}
.cf-time-updated i.fas, .cf-time-created i.far {
padding-right: 8px;
}
.cf-article-time i:before {
margin-right: 5px;
}
/* 底部 */
#cf-footer {
margin: 1rem 0;
text-align: right;
font-size: 13px;
}
.cf-data-lastupdated {
font-size: 13px;
text-align: right;
display: block;
color: var(--heo-secondtext);
}
/* 个人文章列表层 */
#cf-overlay, #cf-overshow {
position: fixed;
width: 100%;
height: 100%;
}
#cf-overlay {
top: 0;
left: 100%;
background-color: rgba(255, 255, 255, 0.42);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
overflow-y: auto;
pointer-events: all;
transition: all 0.1s ease;
z-index: 998;
}
#cf-overshow {
bottom: 100%;
left: 0;
transition: all 0.3s ease;
z-index: 999;
transition: 0.3s;
}
#cf-overlay.cf-show-now {
left: 0;
}
#cf-overshow.cf-show-now {
bottom: 0;
transition: 0.3s;
}
.cf-overshow {
text-align: center;
border-radius: 20px;
position: absolute;
width: 320px;
min-height: 170px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.093);
background: var(--heo-theme);
}
.cf-overshow-head:hover img.cf-img-avatar {
transform: rotate(360deg);
transition: 0.8s;
}
.cf-overshow .cf-overshow-head a {
color: var(--heo-white);
display: block;
text-align: center;
font-weight: bold;
margin-top: -5px;
padding: 5px 8px 5px;
text-decoration: none;
}
.cf-overshow img.cf-img-avatar {
background: #fff;
width: 80px;
height: 80px;
border-radius: 50%;
margin: -45px auto 0 !important;
box-shadow: 0 12px 40px rgb(0 0 0 / 9%);
transform: rotate(-360deg);
transition: 0.8s;
}
.cf-overshow p {
margin: 0.3rem 5px;
position: relative;
display: flex;
flex-direction: column;
}
.cf-overshow p a.cf-article-title {
text-decoration: none !important;
display: block;
text-align: justify;
position: relative;
z-index: 2;
font-size: 15px;
line-height: 1.2;
letter-spacing: normal;
max-height: 50px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
display: box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
color: var(--heo-fontcolor);
}
.cf-overshow p span {
z-index: 1;
font-size: 12px;
margin-left: auto;
}
#cf-container .cf-overshow p a:hover {
letter-spacing: 1px;
transition: 0.3s;
}
.cf-overshow .cf-overshow-content {
padding: 10px 15px 10px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background: var(--heo-card-bg);
display: flex;
flex-direction: column;
max-height: 70vh;
overflow: scroll;
}
.cf-overshow .cf-overshow-content .cf-article-title {
margin: 0;
}
#cf-overshow .cf-overshow-close {
position: sticky;
display: block;
width: 100%;
height: 100%;
}
/* 颜色 */
#cf-state, #cf-more {
background: var(--heo-card-bg);
color: var(--heo-fontcolor);
border: var(--style-border);
box-shadow: var(--heo-shadow-border);
}
#cf-change, .cf-time-updated, .cf-time-created, .cf-article-floor {
color: var(--heo-fontcolor);
opacity: 0.4;
transition: 0.3s;
}
.cf-article-author, .cf-article a.cf-article-title, .cf-article:hover .cf-article-floor, .cf-article:hover .cf-time-created, .cf-article:hover .cf-time-updated {
color: var(--heo-fontcolor);
opacity: 1;
}
.cf-article {
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: var(--heo-shadow-border);
margin: 8px 0;
border-radius: 8px;
font-weight: bolder;
overflow: hidden;
transition: all ease-out .3s;
position: relative;
padding: 0.8rem;
padding-bottom: 0.4rem;
width: calc(50% - 12px);
background: var(--heo-card-bg);
border: var(--style-border-always);
}
.cf-article:hover {
transition: 0.3s;
border: var(--style-border-hover);
box-shadow: var(--heo-shadow-main);
}
@media screen and (max-width: 768px) {
.cf-article {
box-shadow: none !important;
width: 100%;
}
}
#cf-change span:hover {
color: var(--heo-lighttext);
cursor: pointer;
}
#cf-change .cf-change-now {
color: var(--heo-lighttext);
font-weight: 800;
}
.cf-overshow p a:hover {
color: var(--heo-lighttext) !important;
}
.cf-overshow p span {
color: var(--heo-fontcolor);
opacity: 0.4;
}
/* 暗色主题 */
.dark-theme #cf-overlay, .theme-dark #cf-overlay {
background-color: rgba(59, 61, 66, 0.42);
}
.dark-theme .cf-overshow, .theme-dark .cf-overshow {
background: #292a2d;
}
.dark-theme .cf-overshow p a, .theme-dark .cf-overshow p a {
color: var(--lmm-fontcolor);
}
.dark-theme .cf-overshow .cf-overshow-content, .theme-dark .cf-overshow .cf-overshow-content {
background: #eaeaea;
}
.dark-theme #cf-state, .dark-theme #cf-more, .theme-dark #cf-state, .theme-dark #cf-more {
background: var(--lmm-dack-background);
color: var(--lmm-dark-fontcolor);
}
.dark-theme #cf-change, .dark-theme .cf-time-updated, .dark-theme .cf-time-created, .dark-theme .cf-article-floor, .theme-dark #cf-change, .theme-dark .cf-time-updated, .theme-dark .cf-time-created, .theme-dark .cf-article-floor {
color: var(--lmm-dark-floorcolor);
}
.dark-theme .cf-article-author, .dark-theme .cf-article a.cf-article-title, .theme-dark .cf-article-author, .theme-dark .cf-article a.cf-article-title {
color: var(--lmm-dark-fontcolor);
}
.dark-theme .cf-article, .theme-dark .cf-article {
background: var(--lmm-dack-background);
}
.dark-theme .cf-article:hover .cf-article-floor, .dark-theme .cf-article:hover .cf-time-created, .dark-theme .cf-article:hover .cf-time-updated, .dark-theme .cf-overshow p span, .theme-dark .cf-article:hover .cf-article-floor, .theme-dark .cf-article:hover .cf-time-created, .theme-dark .cf-article:hover .cf-time-updated, .theme-dark .cf-overshow p span {
color: var(--lmm-dark-fontcolor);
}
/* 移动端适配 */
@media screen and (max-width: 400px) {
#cf-state {
font-size: 14px;
}
.cf-article-time i {
display: none;
}
}
@media screen and (max-width: 300px) {
#cf-state, .cf-article-time {
display: none;
}
}

View File

@ -0,0 +1,363 @@
/*
Last Modified time : 20220211 15:38 by https://immmmm.com
已适配 FriendCircle 公共库和主库
*/
//默认数据
var fdata = {
jsonurl: '',
apiurl: 'https://moments.0206.ink/',
apipublicurl: '', //默认公共库
initnumber: 20, //首次加载文章数
stepnumber: 20, //更多加载文章数
article_sort: 'created', //文章排序 updated or created
error_img: 'https://sdn.geekzu.org/avatar/57d8260dfb55501c37dde588e7c3852c'
}
//可通过 var fdataUser 替换默认值
if (typeof (fdataUser) !== "undefined") {
for (var key in fdataUser) {
if (fdataUser[key]) {
fdata[key] = fdataUser[key];
}
}
}
var article_num = '', sortNow = '', UrlNow = '', friends_num = ''
var container = document.getElementById('cf-container') || document.getElementById('fcircleContainer');
// 获取本地 排序值、加载apiUrl实现记忆效果
var localSortNow = localStorage.getItem("sortNow")
var localUrlNow = localStorage.getItem("urlNow")
if (localSortNow && localUrlNow) {
sortNow = localSortNow
UrlNow = localUrlNow
} else {
sortNow = fdata.article_sort
if (fdata.jsonurl) {
UrlNow = fdata.apipublicurl + 'postjson?jsonlink=' + fdata.jsonurl + "&"
} else if (fdata.apiurl) {
UrlNow = fdata.apiurl + 'all?'
} else {
UrlNow = fdata.apipublicurl + 'all?'
}
console.log("当前模式:" + UrlNow)
localStorage.setItem("urlNow", UrlNow)
localStorage.setItem("sortNow", sortNow)
}
// 打印基本信息
function loadStatistical(sdata) {
article_num = sdata.article_num
friends_num = sdata.friends_num
var messageBoard = `
<div id="cf-state" class="cf-new-add">
<div class="cf-state-data">
<div class="cf-data-friends" onclick="openToShow()">
<span class="cf-label">订阅</span>
<span class="cf-message">${sdata.friends_num}</span>
</div>
<div class="cf-data-active" onclick="changeEgg()">
<span class="cf-label">活跃</span>
<span class="cf-message">${sdata.active_num}</span>
</div>
<div class="cf-data-article" onclick="clearLocal()">
<span class="cf-label">日志</span>
<span class="cf-message">${sdata.article_num}</span>
</div>
</div>
<div id="cf-change">
<span id="cf-change-created" data-sort="created" onclick="changeSort(event)" class="${sortNow == 'created' ? 'cf-change-now' : ''}">Created</span> | <span id="cf-change-updated" data-sort="updated" onclick="changeSort(event)" class="${sortNow == 'updated' ? 'cf-change-now' : ''}" >Updated</span>
</div>
</div>
`;
var loadMoreBtn = `
`;
if (container) {
// container.insertAdjacentHTML('beforebegin', messageBoard);
container.insertAdjacentHTML('afterend', loadMoreBtn);
}
}
// 打印文章内容 cf-article
function loadArticleItem(datalist, start, end) {
var articleItem = '';
var articleNum = article_num;
var endFor = end
if (end > articleNum) {
endFor = articleNum
}
if (start < articleNum) {
for (var i = start; i < endFor; i++) {
var item = datalist[i];
articleItem += `
<div class="cf-article">
<a class="cf-article-title" href="${item.link}" target="_blank" rel="noopener nofollow" data-title="${item.title}">${item.title}</a>
<span class="cf-article-floor">${item.floor}</span>
<div class="cf-article-avatar no-lightbox flink-item-icon">
<a onclick="openMeShow(event)" data-link="${item.link}" class="" target="_blank" rel="noopener nofollow" href="javascript:;"><img class="cf-img-avatar avatar" src= "${item.avatar}" alt="avatar" onerror="this.src='${fdata.error_img}'; this.onerror = null;"><span class="cf-article-author">${item.author}</span></a>
<span class="cf-article-time">
<span class="cf-time-created" style="${sortNow == 'created' ? '' : 'display:none'}">${item.created}</span>
<span class="cf-time-updated" style="${sortNow == 'updated' ? '' : 'display:none'}"><i class="fas fa-history">更新于</i>${item.updated}</span>
</span>
</div>
</div>
`;
}
container.insertAdjacentHTML('beforeend', articleItem);
// 预载下一页文章
fetchNextArticle()
} else {
// 文章加载到底
document.getElementById('cf-more').outerHTML = `<div id="cf-more" class="cf-new-add" onclick="loadNoArticle()"><small>一切皆有尽头!</small></div>`
}
}
// 打印个人卡片 cf-overshow
function loadFcircleShow(userinfo, articledata) {
var showHtml = `
<div class="cf-overshow">
<div class="cf-overshow-head">
<img class="cf-img-avatar avatar" src= "${userinfo.avatar}" alt="avatar" onerror="this.src='${fdata.error_img}'; this.onerror = null;">
<a class="" target="_blank" rel="noopener nofollow" href="${userinfo.link}">${userinfo.author}</a>
</div>
<div class="cf-overshow-content">
`
for (var i = 0; i < userinfo.article_num; i++) {
var item = articledata[i];
showHtml += `
<p><a class="cf-article-title" href="${item.link}" target="_blank" rel="noopener nofollow" data-title="${item.title}">${item.title}</a><span>${item.created}</span></p>
`
}
showHtml += '</div></div>'
document.getElementById('cf-overshow').insertAdjacentHTML('beforeend', showHtml);
document.getElementById('cf-overshow').className = 'cf-show-now';
}
// 预载下一页文章,存为本地数据 nextArticle
function fetchNextArticle() {
var start = document.getElementsByClassName('cf-article').length
var end = start + fdata.stepnumber
var articleNum = article_num;
if (end > articleNum) {
end = articleNum
}
if (start < articleNum) {
UrlNow = localStorage.getItem("urlNow")
var fetchUrl = UrlNow + "rule=" + sortNow + "&start=" + start + "&end=" + end
//console.log(fetchUrl)
fetch(fetchUrl)
.then(res => res.json())
.then(json => {
var nextArticle = eval(json.article_data);
console.log("已预载" + "?rule=" + sortNow + "&start=" + start + "&end=" + end)
localStorage.setItem("nextArticle", JSON.stringify(nextArticle))
})
} else if (start = articleNum) {
document.getElementById('cf-more').outerHTML = `<div id="cf-more" class="cf-new-add" onclick="loadNoArticle()"><small>一切皆有尽头!</small></div>`
}
}
// 显示下一页文章,从本地缓存 nextArticle 中获取
function loadNextArticle() {
var nextArticle = JSON.parse(localStorage.getItem("nextArticle"));
var articleItem = ""
for (var i = 0; i < nextArticle.length; i++) {
var item = nextArticle[i];
articleItem += `
<div class="cf-article">
<a class="cf-article-title" href="${item.link}" target="_blank" rel="noopener nofollow" data-title="${item.title}">${item.title}</a>
<span class="cf-article-floor">${item.floor}</span>
<div class="cf-article-avatar no-lightbox flink-item-icon">
<a onclick="openMeShow(event)" data-link="${item.link}" class="" target="_blank" rel="noopener nofollow" href="javascript:;"><img class="cf-img-avatar avatar" src= "https://bu.dusays.com/2023/03/03/6401a7902b8de.png" data-lazy-src="${item.avatar}" alt="avatar" onerror="this.src='${fdata.error_img}'; this.onerror = null;"><span class="cf-article-author">${item.author}</span></a>
<span class="cf-article-time">
<span class="cf-time-created" style="${sortNow == 'created' ? '' : 'display:none'}">${item.created}</span>
<span class="cf-time-updated" style="${sortNow == 'updated' ? '' : 'display:none'}"><i class="fas fa-history">更新于</i>${item.updated}</span>
</span>
</div>
</div>
`;
}
container.insertAdjacentHTML('beforeend', articleItem);
// 同时预载下一页文章
fetchNextArticle()
}
// 没有更多文章
function loadNoArticle() {
var articleSortData = sortNow + "ArticleData"
localStorage.removeItem(articleSortData)
localStorage.removeItem("statisticalData")
//localStorage.removeItem("sortNow")
document.getElementById('cf-more').remove()
window.scrollTo(0, document.getElementsByClassName('cf-state').offsetTop)
}
// 清空本地数据
function clearLocal() {
localStorage.removeItem("updatedArticleData")
localStorage.removeItem("createdArticleData")
localStorage.removeItem("nextArticle")
localStorage.removeItem("statisticalData")
localStorage.removeItem("sortNow")
localStorage.removeItem("urlNow")
location.reload();
}
//
function checkVersion() {
var url = fdata.apiurl + "version"
fetch(url)
.then(res => res.json())
.then(json => {
console.log(json)
var nowStatus = json.status, nowVersion = json.current_version, newVersion = json.latest_version
var versionID = document.getElementById('cf-version-up')
if (nowStatus == 0) {
versionID.innerHTML = "当前版本v" + nowVersion
} else if (nowStatus == 1) {
versionID.innerHTML = "发现新版本v" + nowVersion + " ↦ " + newVersion
} else {
versionID.innerHTML = "网络错误,检测失败!"
}
})
}
// 切换为公共全库
function changeEgg() {
//有自定义json或api执行切换
if (fdata.jsonurl || fdata.apiurl) {
document.querySelectorAll('.cf-new-add').forEach(el => el.remove());
localStorage.removeItem("updatedArticleData")
localStorage.removeItem("createdArticleData")
localStorage.removeItem("nextArticle")
localStorage.removeItem("statisticalData")
container.innerHTML = ""
UrlNow = localStorage.getItem("urlNow")
//console.log("新"+UrlNow)
var UrlNowPublic = fdata.apipublicurl + 'all?'
if (UrlNow !== UrlNowPublic) { //非完整默认公开库
changeUrl = fdata.apipublicurl + 'all?'
} else {
if (fdata.jsonurl) {
changeUrl = fdata.apipublicurl + 'postjson?jsonlink=' + fdata.jsonurl + "&"
} else if (fdata.apiurl) {
changeUrl = fdata.apiurl + 'all?'
}
}
localStorage.setItem("urlNow", changeUrl)
FetchFriendCircle(sortNow, changeUrl)
} else {
clearLocal();
}
}
// 首次加载文章
function FetchFriendCircle(sortNow, changeUrl) {
var end = fdata.initnumber
var fetchUrl = UrlNow + "rule=" + sortNow + "&start=0&end=" + end
if (changeUrl) {
fetchUrl = changeUrl + "rule=" + sortNow + "&start=0&end=" + end
}
//console.log(fetchUrl)
fetch(fetchUrl)
.then(res => res.json())
.then(json => {
var statisticalData = json.statistical_data;
var articleData = eval(json.article_data);
var articleSortData = sortNow + "ArticleData";
loadStatistical(statisticalData);
loadArticleItem(articleData, 0, end)
localStorage.setItem("statisticalData", JSON.stringify(statisticalData))
localStorage.setItem(articleSortData, JSON.stringify(articleData))
})
}
// 点击切换排序
function changeSort(event) {
sortNow = event.currentTarget.dataset.sort
localStorage.setItem("sortNow", sortNow)
document.querySelectorAll('.cf-new-add').forEach(el => el.remove());
container.innerHTML = "";
changeUrl = localStorage.getItem("urlNow")
//console.log(changeUrl)
initFriendCircle(sortNow, changeUrl)
if (fdata.apiurl) {
checkVersion()
}
}
//查询个人文章列表
function openMeShow(event) {
event.preventDefault()
var parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var meLink = event.currentTarget.dataset.link.replace(parse_url, '$1:$2$3')
console.log(meLink)
var fetchUrl = ''
if (fdata.apiurl) {
fetchUrl = fdata.apiurl + "post?link=" + meLink
} else {
fetchUrl = fdata.apipublicurl + "post?link=" + meLink
}
//console.log(fetchUrl)
if (noClick == 'ok') {
noClick = 'no'
fetchShow(fetchUrl)
}
}
// 关闭 show
function closeShow() {
document.getElementById('cf-overlay').className -= 'cf-show-now';
document.getElementById('cf-overshow').className -= 'cf-show-now';
document.getElementById('cf-overshow').innerHTML = '';
}
// 点击开往
var noClick = 'ok';
function openToShow() {
var fetchUrl = ''
if (fdata.apiurl) {
fetchUrl = fdata.apiurl + "post"
} else {
fetchUrl = fdata.apipublicurl + "post"
}
//console.log(fetchUrl)
if (noClick == 'ok') {
noClick = 'no'
fetchShow(fetchUrl)
}
}
// 展示个人文章列表
function fetchShow(url) {
var closeHtml = `
<div class="cf-overshow-close" onclick="closeShow()"></div>
`
document.getElementById('cf-overlay').className = 'cf-show-now';
document.getElementById('cf-overshow').insertAdjacentHTML('afterbegin', closeHtml);
console.log("开往" + url)
fetch(url)
.then(res => res.json())
.then(json => {
//console.log(json)
noClick = 'ok'
var statisticalData = json.statistical_data;
var articleData = eval(json.article_data);
loadFcircleShow(statisticalData, articleData)
})
}
// 初始化方法
function initFriendCircle(sortNow, changeUrl) {
var articleSortData = sortNow + "ArticleData";
var localStatisticalData = JSON.parse(localStorage.getItem("statisticalData"));
var localArticleData = JSON.parse(localStorage.getItem(articleSortData));
container.innerHTML = "";
FetchFriendCircle(sortNow, changeUrl);
}
// 执行初始化
if(document.getElementById('cf-container')){
initFriendCircle(sortNow);
}

Some files were not shown because too many files have changed in this diff Show More