[feat] plugins refactoring
This commit is contained in:
parent
97d3bb4efb
commit
23aab88e04
157
_config.yml
157
_config.yml
|
@ -289,11 +289,6 @@ footer:
|
||||||
|
|
||||||
######## Tag Plugins ########
|
######## Tag Plugins ########
|
||||||
tag_plugins:
|
tag_plugins:
|
||||||
# {% link %}
|
|
||||||
linkcard:
|
|
||||||
# 设置 api 可以自动提取网页标题、图标,服务部署方法:https://github.com/xaoxuu/site-info-api/
|
|
||||||
# 接口测试通过后,把按钮的 href 部分替换成 ${href} 之后填写到下方,例如:https://api.vlts.cc/site_info/v1?url=${href}
|
|
||||||
api:
|
|
||||||
# {% box %} / {% note %}
|
# {% box %} / {% note %}
|
||||||
note:
|
note:
|
||||||
default_color: '' # light, dark, red, orange, yellow, green, cyan, blue, purple, warning, error
|
default_color: '' # light, dark, red, orange, yellow, green, cyan, blue, purple, warning, error
|
||||||
|
@ -367,42 +362,82 @@ tag_plugins:
|
||||||
ratio: square # origin / square
|
ratio: square # origin / square
|
||||||
|
|
||||||
|
|
||||||
|
# 基础依赖
|
||||||
|
dependencies:
|
||||||
######## JS Plugins ########
|
|
||||||
plugins:
|
|
||||||
## required plugins ##
|
|
||||||
# jquery
|
|
||||||
jquery: https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js
|
jquery: https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js
|
||||||
|
|
||||||
# stellar api
|
|
||||||
stellar:
|
|
||||||
sites: /js/plugins/sites.js
|
|
||||||
friends: /js/plugins/friends.js
|
|
||||||
ghinfo: /js/plugins/ghinfo.js
|
|
||||||
timeline: /js/plugins/timeline.js
|
|
||||||
linkcard: /js/plugins/linkcard.js
|
|
||||||
fcircle: /js/plugins/fcircle.js
|
|
||||||
weibo: /js/plugins/weibo.js
|
|
||||||
memos: /js/plugins/memos.js
|
|
||||||
marked: /js/plugins/marked.js
|
|
||||||
|
|
||||||
marked: https://cdn.bootcdn.net/ajax/libs/marked/4.0.18/marked.min.js
|
marked: https://cdn.bootcdn.net/ajax/libs/marked/4.0.18/marked.min.js
|
||||||
|
|
||||||
## optional plugins ##
|
|
||||||
|
# 内置服务,按需加载(页面内用到了就会加载,没有用到就不会加载)
|
||||||
|
services:
|
||||||
|
# 外部 md 渲染
|
||||||
|
mdrender:
|
||||||
|
js: /js/services/mdrender.js
|
||||||
|
# 数据填充类
|
||||||
|
siteinfo:
|
||||||
|
js: /js/services/siteinfo.js
|
||||||
|
# 设置 api 可以自动提取网页标题、图标,服务部署方法:https://github.com/xaoxuu/site-info-api/
|
||||||
|
# 接口测试通过后,把按钮的 href 部分替换成 ${href} 之后填写到下方,例如:https://api.vlts.cc/site_info/v1?url=${href}
|
||||||
|
api:
|
||||||
|
ghinfo:
|
||||||
|
js: /js/services/ghinfo.js
|
||||||
|
# 网格布局类
|
||||||
|
sites:
|
||||||
|
js: /js/services/sites.js
|
||||||
|
friends:
|
||||||
|
js: /js/services/friends.js
|
||||||
|
# 列表布局类
|
||||||
|
timeline:
|
||||||
|
js: /js/services/timeline.js
|
||||||
|
fcircle:
|
||||||
|
js: /js/services/fcircle.js
|
||||||
|
weibo:
|
||||||
|
js: /js/services/weibo.js
|
||||||
|
memos:
|
||||||
|
js: /js/services/memos.js
|
||||||
|
|
||||||
|
|
||||||
|
# 扩展插件接入方法:(插件名下面用 #plugin# 代替)
|
||||||
|
# 1. 在这里增加 #plugin# 配置,至少赢含有 enable 字段,默认为空(不启用)
|
||||||
|
# 2. 新建文件 layout/_plugins/#plugin#.ejs 文件中设置编写加载代码。
|
||||||
|
# 2.1. 在该文件中可以直接使用 conf 来读取用户在【步骤 1】填写的配置字段内容
|
||||||
|
# 2.2. 如果需要引入 css 或 js,可以使用 utils.css(xxx)、utils.js(xxx),具体可参考 layout/_plugins/fancybox.ejs
|
||||||
|
# 2.3. 如果需要本地 js 文件,请放入 /source/js/plugins 文件夹中,引入方式为:utils.js('/js/plugins/xxx.js');
|
||||||
|
# 3. 如果这个插件只需要引入外部文件,可以在【步骤 1】处增加 inject 字段,而无需进入【步骤 2】创建 ejs,参考 katex
|
||||||
|
plugins:
|
||||||
|
|
||||||
# preload
|
# preload
|
||||||
preload:
|
preload:
|
||||||
enable: true
|
enable: true
|
||||||
service: flying_pages # flying_pages
|
service: flying_pages # flying_pages
|
||||||
flying_pages: https://cdn.bootcdn.net/ajax/libs/flying-pages/2.1.2/flying-pages.min.js
|
flying_pages: https://cdn.bootcdn.net/ajax/libs/flying-pages/2.1.2/flying-pages.min.js
|
||||||
|
|
||||||
# image lazyload
|
# lazyload
|
||||||
# https://www.npmjs.com/package/vanilla-lazyload
|
# https://www.npmjs.com/package/vanilla-lazyload
|
||||||
lazyload:
|
lazyload:
|
||||||
enable: true # [hexo clean && hexo s] is required after changing this value.
|
enable: true # [hexo clean && hexo s] is required after changing this value.
|
||||||
js: https://cdn.bootcdn.net/ajax/libs/vanilla-lazyload/17.8.4/lazyload.min.js
|
js: https://cdn.bootcdn.net/ajax/libs/vanilla-lazyload/17.8.4/lazyload.min.js
|
||||||
transition: fade # blur, fade
|
transition: fade # blur, fade
|
||||||
|
|
||||||
|
# https://fancyapps.com/docs/ui/fancybox/
|
||||||
|
# available for {% image xxx %}
|
||||||
|
fancybox:
|
||||||
|
enable: true
|
||||||
|
loader: /js/plugins/fancybox-loader.js
|
||||||
|
js: https://cdn.bootcdn.net/ajax/libs/fancyapps-ui/5.0.22/fancybox/fancybox.umd.min.js
|
||||||
|
css: https://cdn.bootcdn.net/ajax/libs/fancyapps-ui/5.0.22/fancybox/fancybox.min.css
|
||||||
|
# 让 md 语法图片支持放大可以这样写: .md-text img:not([class]), .md-text .image img
|
||||||
|
# 可以处理评论区的图片(不支持 iframe 类评论系统)例如:
|
||||||
|
# 使用 twikoo 评论可以写: .tk-content img:not([class*="emo"])
|
||||||
|
# 使用 waline 评论可以写: #waline_container .vcontent img
|
||||||
|
selector: .timenode p>img # 多个选择器用英文逗号隔开
|
||||||
|
|
||||||
|
# swiper
|
||||||
|
swiper:
|
||||||
|
enable: true
|
||||||
|
css: https://unpkg.com/swiper@10.3.1/swiper-bundle.min.css
|
||||||
|
js: https://unpkg.com/swiper@10.3.1/swiper-bundle.min.js
|
||||||
|
|
||||||
# https://scrollrevealjs.org/api/reveal.html
|
# https://scrollrevealjs.org/api/reveal.html
|
||||||
scrollreveal:
|
scrollreveal:
|
||||||
enable: #true
|
enable: #true
|
||||||
|
@ -412,31 +447,26 @@ plugins:
|
||||||
interval: 100 # ms
|
interval: 100 # ms
|
||||||
scale: 1 # 0.1~1
|
scale: 1 # 0.1~1
|
||||||
|
|
||||||
# https://fancyapps.com/docs/ui/fancybox/
|
# AI 摘要
|
||||||
# available for {% image xxx %}
|
# https://github.com/zhheo/Post-Abstract-AI
|
||||||
fancybox:
|
tianli_gpt:
|
||||||
enable: true
|
enable: #true
|
||||||
js: https://cdn.bootcdn.net/ajax/libs/fancyapps-ui/5.0.22/fancybox/fancybox.umd.min.js
|
js: https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.15.2/tianli_gpt.min.js
|
||||||
css: https://cdn.bootcdn.net/ajax/libs/fancyapps-ui/5.0.22/fancybox/fancybox.min.css
|
field: post # all, post, wiki
|
||||||
# 让 md 语法图片支持放大可以这样写: .md-text img:not([class]), .md-text .image img
|
api: 5Q5mpqRK5DkwT1X9Gi5e # tianli_gpt key
|
||||||
# 可以处理评论区的图片(不支持 iframe 类评论系统)例如:
|
limit: 1000 # 设置提交的字数限制,默认为1000字,上限为5000,超过5000字符将被截断,不能为空
|
||||||
# 使用 twikoo 评论可以写: .tk-content img:not([class*="emo"])
|
typingAnimate: true # 打字机动画
|
||||||
# 使用 waline 评论可以写: #waline_container .vcontent img
|
|
||||||
selector: # 多个选择器用英文逗号隔开
|
|
||||||
|
|
||||||
# swiper
|
# Katex - The fastest math typesetting library for the web
|
||||||
swiper:
|
# https://katex.org/docs/autorender.html
|
||||||
enable: true
|
# https://github.com/KaTeX/KaTeX
|
||||||
css: https://unpkg.com/swiper@10.3/swiper-bundle.min.css
|
# 使用 hexo-renderer-markdown-it-plus 作为公式渲染器:npm uninstall hexo-renderer-marked --save npm install hexo-renderer-markdown-it-plus --save
|
||||||
js: https://unpkg.com/swiper@10.3/swiper-bundle.min.js
|
katex:
|
||||||
|
enable: #true # 可以在特定文章的 front-matter 中设置 katex: true 来开启,也可以在这里设置全局开启
|
||||||
|
inject: |
|
||||||
# 赫蹏 (Heti) - 专为中文网页内容设计的排版样式增强
|
<link rel="stylesheet" href="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
|
||||||
# https://github.com/sivan/heti
|
<script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
|
||||||
heti:
|
<script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"onload="renderMathInElement(document.body);"></script>
|
||||||
enable: false # 此插件会和代码块冲突,仅适用于纯中文博主。
|
|
||||||
css: https://unpkg.com/heti@0.9.2/umd/heti.min.css
|
|
||||||
js: https://unpkg.com/heti@0.9.2/umd/heti-addon.min.js
|
|
||||||
|
|
||||||
# MathJax
|
# MathJax
|
||||||
# 需在Markdown文件开头加入mathjax: true
|
# 需在Markdown文件开头加入mathjax: true
|
||||||
|
@ -445,16 +475,6 @@ plugins:
|
||||||
enable: # true # 可以在特定文章的 front-matter 中设置 mathjax: true 来开启,也可以在这里设置全局开启
|
enable: # true # 可以在特定文章的 front-matter 中设置 mathjax: true 来开启,也可以在这里设置全局开启
|
||||||
js: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML
|
js: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.6/MathJax.js?config=TeX-AMS-MML_HTMLorMML
|
||||||
|
|
||||||
# Katex - The fastest math typesetting library for the web
|
|
||||||
# https://katex.org/docs/autorender.html
|
|
||||||
# https://github.com/KaTeX/KaTeX
|
|
||||||
# 使用 hexo-renderer-markdown-it-plus 作为公式渲染器:npm uninstall hexo-renderer-marked --save npm install hexo-renderer-markdown-it-plus --save
|
|
||||||
katex:
|
|
||||||
enable: # true # 可以在特定文章的 front-matter 中设置 katex: true 来开启,也可以在这里设置全局开启
|
|
||||||
min_css: <link rel="stylesheet" href="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
|
|
||||||
min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
|
|
||||||
auto_render_min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"onload="renderMathInElement(document.body);"></script>
|
|
||||||
|
|
||||||
# Mermaid - markdwon to flow chart, seq chart, class chart ...
|
# Mermaid - markdwon to flow chart, seq chart, class chart ...
|
||||||
# 需要安装 npm install --save hexo-filter-mermaid-diagrams
|
# 需要安装 npm install --save hexo-filter-mermaid-diagrams
|
||||||
# 使用时 需要在Markdown文件开头加入 mermaid: true
|
# 使用时 需要在Markdown文件开头加入 mermaid: true
|
||||||
|
@ -475,19 +495,18 @@ plugins:
|
||||||
# 代码块复制按钮
|
# 代码块复制按钮
|
||||||
copycode:
|
copycode:
|
||||||
enable: true
|
enable: true
|
||||||
js: /js/plugins/copycode.js
|
|
||||||
default_text: 'Copy'
|
default_text: 'Copy'
|
||||||
success_text: 'Copied'
|
success_text: 'Copied'
|
||||||
toast: 复制成功
|
toast: 复制成功
|
||||||
|
|
||||||
# AI 摘要
|
# 赫蹏 (Heti) - 专为中文网页内容设计的排版样式增强
|
||||||
# https://github.com/zhheo/Post-Abstract-AI
|
# https://github.com/sivan/heti
|
||||||
tianli_gpt:
|
heti:
|
||||||
enable: false
|
enable: false # 此插件会和代码块冲突,仅适用于纯中文博主。
|
||||||
field: post # all, post, wiki
|
css: https://unpkg.com/heti@0.9.2/umd/heti.min.css
|
||||||
api: 5Q5mpqRK5DkwT1X9Gi5e # tianli_gpt key
|
js: https://unpkg.com/heti@0.9.2/umd/heti-addon.min.js
|
||||||
limit: 1000 # 设置提交的字数限制,默认为1000字,上限为5000,超过5000字符将被截断,不能为空
|
|
||||||
typingAnimate: true # 打字机动画
|
|
||||||
|
|
||||||
style:
|
style:
|
||||||
prefers_theme: auto # auto / light / dark
|
prefers_theme: auto # auto / light / dark
|
||||||
|
|
|
@ -16,4 +16,4 @@ page.robots = 'none';
|
||||||
<br><br>
|
<br><br>
|
||||||
<a class='button' id='back' href="<%- config.root %>"><%- __('page.error.action') %></a>
|
<a class='button' id='back' href="<%- config.root %>"><%- __('page.error.action') %></a>
|
||||||
</article>
|
</article>
|
||||||
<%- partial('_partial/plugins/comments/layout') %>
|
<%- partial('_partial/comments/layout') %>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
function load_artalk() {
|
function load_artalk() {
|
||||||
if (!document.querySelectorAll("#artalk_container")[0]) return;
|
if (!document.querySelectorAll("#artalk_container")[0]) return;
|
||||||
stellar.loadCSS('<%- theme.comments.artalk.css %>');
|
utils.css('<%- theme.comments.artalk.css %>');
|
||||||
stellar.loadScript('<%- theme.comments.artalk.js %>', {defer: true}).then(function () {
|
utils.js('<%- theme.comments.artalk.js %>', {defer: true}).then(function () {
|
||||||
const el = document.getElementById("artalk_container");
|
const el = document.getElementById("artalk_container");
|
||||||
var path = el.getAttribute('comment_id');
|
var path = el.getAttribute('comment_id');
|
||||||
if (!path) {
|
if (!path) {
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
function loadJS() {
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
const els = document.querySelectorAll("#comments #giscus");
|
const els = document.querySelectorAll("#comments #giscus");
|
||||||
if (els.length === 0) return;
|
if (els.length === 0) return;
|
||||||
els.forEach((el, i) => {
|
els.forEach((el, i) => {
|
||||||
|
@ -18,8 +18,5 @@
|
||||||
}
|
}
|
||||||
el.appendChild(script);
|
el.appendChild(script);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
window.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
loadJS();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
function load_twikoo() {
|
function load_twikoo() {
|
||||||
if (!document.querySelectorAll("#twikoo_container")[0]) return;
|
if (!document.querySelectorAll("#twikoo_container")[0]) return;
|
||||||
stellar.loadScript('<%- theme.comments.twikoo.js %>', {defer: true}).then(function () {
|
utils.js('<%- theme.comments.twikoo.js %>', {defer: true}).then(function () {
|
||||||
const el = document.getElementById("twikoo_container");
|
const el = document.getElementById("twikoo_container");
|
||||||
var path = el.getAttribute('comment_id');
|
var path = el.getAttribute('comment_id');
|
||||||
if (!path) {
|
if (!path) {
|
|
@ -1,8 +1,8 @@
|
||||||
<script>
|
<script>
|
||||||
function load_comment(){
|
function load_comment(){
|
||||||
if(!document.getElementById("waline_container"))return;
|
if(!document.getElementById("waline_container"))return;
|
||||||
stellar.loadCSS('<%- theme.comments.waline.css %>');
|
utils.css('<%- theme.comments.waline.css %>');
|
||||||
stellar.loadScript('<%- theme.comments.waline.js %>', {defer:true}).then(function () {
|
utils.js('<%- theme.comments.waline.js %>', {defer:true}).then(function () {
|
||||||
const el = document.getElementById("waline_container");
|
const el = document.getElementById("waline_container");
|
||||||
var path = el.getAttribute('comment_id');
|
var path = el.getAttribute('comment_id');
|
||||||
if (!path) {
|
if (!path) {
|
|
@ -128,6 +128,5 @@ function custom_inject() {
|
||||||
<%- css(theme.style.codeblock.highlightjs_theme) %>
|
<%- css(theme.style.codeblock.highlightjs_theme) %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<%- partial('plugins/parser/head') %>
|
|
||||||
<%- custom_inject() %>
|
<%- custom_inject() %>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -51,7 +51,7 @@ function div_default() {
|
||||||
|
|
||||||
// 摘要
|
// 摘要
|
||||||
el += '<div class="excerpt';
|
el += '<div class="excerpt';
|
||||||
if (theme.plugins.heti && theme.plugins.heti.enable) {
|
if (theme.plugins.heti?.enable) {
|
||||||
el += ' heti';
|
el += ' heti';
|
||||||
}
|
}
|
||||||
el += '">';
|
el += '">';
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
<% if (page.layout === 'post' || (page.wiki?.length > 0)) { %>
|
|
||||||
<script>
|
|
||||||
let tianliGPT_postSelector = 'article.content';
|
|
||||||
let tianliGPT_key = '<%= theme.plugins.tianli_gpt.api %>';
|
|
||||||
let tianliGPT_typingAnimate = '<%= theme.plugins.tianli_gpt.typingAnimate %>';
|
|
||||||
let tianliGPT_wordLimit = <%= theme.plugins.tianli_gpt.limit %>;
|
|
||||||
</script>
|
|
||||||
<script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.15.2/tianli_gpt.min.js"></script>
|
|
||||||
<% } %>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<% if (page.katex == true || theme.plugins.katex.enable == true) { %>
|
|
||||||
<%- partial('katex/head') %>
|
|
||||||
<% } %>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<% if (theme.plugins.katex) { %>
|
|
||||||
<%- theme.plugins.katex.min_css %>
|
|
||||||
<% } %>
|
|
|
@ -1,4 +0,0 @@
|
||||||
<% if (theme.plugins.katex) { %>
|
|
||||||
<%- theme.plugins.katex.min_js %>
|
|
||||||
<%- theme.plugins.katex.auto_render_min_js %>
|
|
||||||
<% } %>
|
|
|
@ -1,29 +0,0 @@
|
||||||
<script type="text/javascript" src="<%- theme.plugins.mermaid.js %>"></script>
|
|
||||||
<script>
|
|
||||||
var mermaid_config = {
|
|
||||||
startOnLoad: true,
|
|
||||||
theme:
|
|
||||||
"<%- theme.style.darkmode %>" == "auto" &&
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
||||||
? "dark"
|
|
||||||
: "<%- theme.plugins.mermaid.theme %>",
|
|
||||||
logLevel: 3,
|
|
||||||
themeVariables: {
|
|
||||||
darkMode: true
|
|
||||||
},
|
|
||||||
flowchart: {
|
|
||||||
useMaxWidth: false,
|
|
||||||
htmlLabels: true,
|
|
||||||
curve: "linear"
|
|
||||||
},
|
|
||||||
gantt: {
|
|
||||||
axisFormat: "%Y/%m/%d"
|
|
||||||
},
|
|
||||||
sequence: {
|
|
||||||
actorMargin: 50
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (window.mermaid) {
|
|
||||||
mermaid.initialize(mermaid_config);
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<% if (page.katex == true || theme.plugins.katex.enable) { %>
|
|
||||||
<%- partial('katex/script') %>
|
|
||||||
<% } %>
|
|
||||||
<% if (page.mathjax == true || theme.plugins.mathjax.enable) { %>
|
|
||||||
<%- partial('mathjax/script') %>
|
|
||||||
<% } %>
|
|
||||||
<% if (page.mermaid == true || theme.plugins.mermaid.enable) { %>
|
|
||||||
<%- partial('mermaid/script') %>
|
|
||||||
<% } %>
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<%
|
||||||
|
|
||||||
|
function custom_inject() {
|
||||||
|
var el = '';
|
||||||
|
for (let item of (config.inject?.script || [])) {
|
||||||
|
el += item;
|
||||||
|
}
|
||||||
|
for (let item of (theme.inject?.script || [])) {
|
||||||
|
el += item;
|
||||||
|
}
|
||||||
|
for (let item of (page.inject?.script || [])) {
|
||||||
|
el += item;
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
%>
|
||||||
|
<%- partial('scripts/defines') %>
|
||||||
|
<%- partial('scripts/utils') %>
|
||||||
|
<%- partial('scripts/sidebar') %>
|
||||||
|
|
||||||
|
<!-- required -->
|
||||||
|
<script src="<%- `${theme.stellar.main_js}?v=${stellar_info('version')}` %>" async></script>
|
||||||
|
|
||||||
|
<!-- optional -->
|
||||||
|
<%- partial('comments/script') %>
|
||||||
|
|
||||||
|
<%- partial('scripts/services') %>
|
||||||
|
<%- partial('../_plugins/index') %>
|
||||||
|
|
||||||
|
<!-- inject -->
|
||||||
|
<%- custom_inject() %>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script type="text/javascript">
|
||||||
|
const ctx = {
|
||||||
|
date_suffix: {
|
||||||
|
just: `<%- __('meta.date_suffix.just') %>`,
|
||||||
|
min: `<%- __('meta.date_suffix.min') %>`,
|
||||||
|
hour: `<%- __('meta.date_suffix.hour') %>`,
|
||||||
|
day: `<%- __('meta.date_suffix.day') %>`,
|
||||||
|
},
|
||||||
|
root : `<%- config.root %>`,
|
||||||
|
};
|
||||||
|
|
||||||
|
// required plugins (only load if needs)
|
||||||
|
if (`<%- theme.search.service %>`) {
|
||||||
|
ctx.search = {};
|
||||||
|
ctx.search.service = `<%- theme.search.service %>`;
|
||||||
|
if (ctx.search.service == 'local_search') {
|
||||||
|
let service_obj = Object.assign({}, `<%- JSON.stringify(theme.search.local_search) %>`);
|
||||||
|
ctx.search[ctx.search.service] = service_obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const def = {
|
||||||
|
avatar: `<%- theme.default.avatar %>`,
|
||||||
|
cover: `<%- theme.default.cover %>`,
|
||||||
|
};
|
||||||
|
const deps = {
|
||||||
|
jquery: `<%- url_for(theme.dependencies.jquery) %>`,
|
||||||
|
marked: `<%- url_for(theme.dependencies.marked) %>`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
|
@ -1,175 +0,0 @@
|
||||||
<%
|
|
||||||
|
|
||||||
function custom_inject() {
|
|
||||||
var el = '';
|
|
||||||
for (let item of (config.inject?.script || [])) {
|
|
||||||
el += item;
|
|
||||||
}
|
|
||||||
for (let item of (theme.inject?.script || [])) {
|
|
||||||
el += item;
|
|
||||||
}
|
|
||||||
for (let item of (page.inject?.script || [])) {
|
|
||||||
el += item;
|
|
||||||
}
|
|
||||||
return el;
|
|
||||||
}
|
|
||||||
|
|
||||||
%>
|
|
||||||
<script type="text/javascript">
|
|
||||||
const stellar = {
|
|
||||||
// 懒加载 css https://github.com/filamentgroup/loadCSS
|
|
||||||
loadCSS: (href, before, media, attributes) => {
|
|
||||||
var doc = window.document;
|
|
||||||
var ss = doc.createElement("link");
|
|
||||||
var ref;
|
|
||||||
if (before) {
|
|
||||||
ref = before;
|
|
||||||
} else {
|
|
||||||
var refs = (doc.body || doc.getElementsByTagName("head")[0]).childNodes;
|
|
||||||
ref = refs[refs.length - 1];
|
|
||||||
}
|
|
||||||
var sheets = doc.styleSheets;
|
|
||||||
if (attributes) {
|
|
||||||
for (var attributeName in attributes) {
|
|
||||||
if (attributes.hasOwnProperty(attributeName)) {
|
|
||||||
ss.setAttribute(attributeName, attributes[attributeName]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ss.rel = "stylesheet";
|
|
||||||
ss.href = href;
|
|
||||||
ss.media = "only x";
|
|
||||||
function ready(cb) {
|
|
||||||
if (doc.body) {
|
|
||||||
return cb();
|
|
||||||
}
|
|
||||||
setTimeout(function () {
|
|
||||||
ready(cb);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ready(function () {
|
|
||||||
ref.parentNode.insertBefore(ss, before ? ref : ref.nextSibling);
|
|
||||||
});
|
|
||||||
var onloadcssdefined = function (cb) {
|
|
||||||
var resolvedHref = ss.href;
|
|
||||||
var i = sheets.length;
|
|
||||||
while (i--) {
|
|
||||||
if (sheets[i].href === resolvedHref) {
|
|
||||||
return cb();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setTimeout(function () {
|
|
||||||
onloadcssdefined(cb);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
function loadCB() {
|
|
||||||
if (ss.addEventListener) {
|
|
||||||
ss.removeEventListener("load", loadCB);
|
|
||||||
}
|
|
||||||
ss.media = media || "all";
|
|
||||||
}
|
|
||||||
if (ss.addEventListener) {
|
|
||||||
ss.addEventListener("load", loadCB);
|
|
||||||
}
|
|
||||||
ss.onloadcssdefined = onloadcssdefined;
|
|
||||||
onloadcssdefined(loadCB);
|
|
||||||
return ss;
|
|
||||||
},
|
|
||||||
|
|
||||||
// 从 butterfly 和 volantis 获得灵感
|
|
||||||
loadScript: (src, opt) => new Promise((resolve, reject) => {
|
|
||||||
var script = document.createElement('script');
|
|
||||||
if (src.startsWith('/')){
|
|
||||||
src = stellar.config.root + src.substring(1);
|
|
||||||
}
|
|
||||||
script.src = src;
|
|
||||||
if (opt) {
|
|
||||||
for (let key of Object.keys(opt)) {
|
|
||||||
script[key] = opt[key]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 默认异步,如果需要同步,第二个参数传入 {} 即可
|
|
||||||
script.async = true
|
|
||||||
}
|
|
||||||
script.onerror = reject
|
|
||||||
script.onload = script.onreadystatechange = function() {
|
|
||||||
const loadState = this.readyState
|
|
||||||
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
|
||||||
script.onload = script.onreadystatechange = null
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
document.head.appendChild(script)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// https://github.com/jerryc127/hexo-theme-butterfly
|
|
||||||
jQuery: (fn) => {
|
|
||||||
if (typeof jQuery === 'undefined') {
|
|
||||||
stellar.loadScript(stellar.plugins.jQuery).then(fn)
|
|
||||||
} else {
|
|
||||||
fn()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
stellar.version = '<%- theme.stellar.version %>';
|
|
||||||
stellar.github = 'https://github.com/xaoxuu/hexo-theme-stellar/tree/<%- theme.stellar.version %>';
|
|
||||||
stellar.config = {
|
|
||||||
date_suffix: {
|
|
||||||
just: '<%- __('meta.date_suffix.just') %>',
|
|
||||||
min: '<%- __('meta.date_suffix.min') %>',
|
|
||||||
hour: '<%- __('meta.date_suffix.hour') %>',
|
|
||||||
day: '<%- __('meta.date_suffix.day') %>',
|
|
||||||
},
|
|
||||||
root : '<%- config.root %>',
|
|
||||||
};
|
|
||||||
|
|
||||||
// required plugins (only load if needs)
|
|
||||||
stellar.plugins = {
|
|
||||||
jQuery: '<%- url_for(theme.plugins.jquery || "https://gcore.jsdelivr.net/npm/jquery@3.6.2/dist/jquery.min.js") %>'
|
|
||||||
};
|
|
||||||
|
|
||||||
if ('<%- theme.search.service %>') {
|
|
||||||
stellar.search = {};
|
|
||||||
stellar.search.service = '<%- theme.search.service %>';
|
|
||||||
if (stellar.search.service == 'local_search') {
|
|
||||||
let service_obj = Object.assign({}, <%- JSON.stringify(theme.search.local_search) %>);
|
|
||||||
stellar.search[stellar.search.service] = service_obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// stellar js
|
|
||||||
stellar.plugins.stellar = Object.assign(<%- JSON.stringify(theme.plugins.stellar) %>);
|
|
||||||
|
|
||||||
stellar.plugins.marked = Object.assign(<%- JSON.stringify(theme.plugins.marked) %>);
|
|
||||||
// optional plugins
|
|
||||||
if ('<%- theme.plugins.lazyload.enable %>' == 'true') {
|
|
||||||
stellar.plugins.lazyload = Object.assign(<%- JSON.stringify(theme.plugins.lazyload) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.swiper.enable %>' == 'true') {
|
|
||||||
stellar.plugins.swiper = Object.assign(<%- JSON.stringify(theme.plugins.swiper) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.scrollreveal.enable %>' == 'true') {
|
|
||||||
stellar.plugins.scrollreveal = Object.assign(<%- JSON.stringify(theme.plugins.scrollreveal) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.preload.enable %>' == 'true') {
|
|
||||||
stellar.plugins.preload = Object.assign(<%- JSON.stringify(theme.plugins.preload) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.fancybox.enable %>' == 'true') {
|
|
||||||
stellar.plugins.fancybox = Object.assign(<%- JSON.stringify(theme.plugins.fancybox) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.heti.enable %>' == 'true') {
|
|
||||||
stellar.plugins.heti = Object.assign(<%- JSON.stringify(theme.plugins.heti) %>);
|
|
||||||
}
|
|
||||||
if ('<%- theme.plugins.copycode.enable %>' == 'true') {
|
|
||||||
stellar.plugins.copycode = Object.assign(<%- JSON.stringify(theme.plugins.copycode) %>);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- required -->
|
|
||||||
<script src="<%- `${theme.stellar.main_js}?v=${stellar_info('version')}` %>" async></script>
|
|
||||||
|
|
||||||
<!-- optional -->
|
|
||||||
<%- partial('../plugins/comments/script') %>
|
|
||||||
<%- partial('../plugins/parser/script') %>
|
|
||||||
|
|
||||||
<!-- inject -->
|
|
||||||
<%- custom_inject() %>
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
<script>
|
||||||
|
ctx.services = {
|
||||||
|
fcircle: `<%- theme.services.fcircle?.js %>`,
|
||||||
|
friends: `<%- theme.services.friends?.js %>`,
|
||||||
|
ghinfo: `<%- theme.services.ghinfo?.js %>`,
|
||||||
|
siteinfo: `<%- theme.services.siteinfo?.js %>`,
|
||||||
|
mdrender: `<%- theme.services.mdrender?.js %>`,
|
||||||
|
memos: `<%- theme.services.memos?.js %>`,
|
||||||
|
sites: `<%- theme.services.sites?.js %>`,
|
||||||
|
timeline: `<%- theme.services.timeline?.js %>`,
|
||||||
|
weibo: `<%- theme.services.weibo?.js %>`,
|
||||||
|
}
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
for (let id of Object.keys(ctx.services)) {
|
||||||
|
const js = ctx.services[id];
|
||||||
|
if (id == 'siteinfo') {
|
||||||
|
const els = document.querySelectorAll('a.link-card[cardlink]');
|
||||||
|
if (els?.length > 0) {
|
||||||
|
utils.js(js, { defer: true }).then(function () {
|
||||||
|
setCardLink(els);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const els = document.getElementsByClassName(`stellar-${id}-api`);
|
||||||
|
if (els?.length > 0) {
|
||||||
|
utils.jq(() => {
|
||||||
|
if (id == 'timeline' || 'memos' || 'marked') {
|
||||||
|
utils.js(deps.marked).then(function () {
|
||||||
|
utils.js(js, { defer: true });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
utils.js(js, { defer: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<script>
|
||||||
|
const sidebar = {
|
||||||
|
leftbar: () => {
|
||||||
|
if (l_body) {
|
||||||
|
l_body.toggleAttribute('leftbar');
|
||||||
|
l_body.removeAttribute('rightbar');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rightbar: () => {
|
||||||
|
if (l_body) {
|
||||||
|
l_body.toggleAttribute('rightbar');
|
||||||
|
l_body.removeAttribute('leftbar');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismiss: () => {
|
||||||
|
if (l_body) {
|
||||||
|
l_body.removeAttribute('leftbar');
|
||||||
|
l_body.removeAttribute('rightbar');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleTOC: () => {
|
||||||
|
document.querySelector('#data-toc').classList.toggle('collapse');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,158 @@
|
||||||
|
<script type="text/javascript">
|
||||||
|
const utils = {
|
||||||
|
// 懒加载 css https://github.com/filamentgroup/loadCSS
|
||||||
|
css: (href, before, media, attributes) => {
|
||||||
|
var doc = window.document;
|
||||||
|
var ss = doc.createElement("link");
|
||||||
|
var ref;
|
||||||
|
if (before) {
|
||||||
|
ref = before;
|
||||||
|
} else {
|
||||||
|
var refs = (doc.body || doc.getElementsByTagName("head")[0]).childNodes;
|
||||||
|
ref = refs[refs.length - 1];
|
||||||
|
}
|
||||||
|
var sheets = doc.styleSheets;
|
||||||
|
if (attributes) {
|
||||||
|
for (var attributeName in attributes) {
|
||||||
|
if (attributes.hasOwnProperty(attributeName)) {
|
||||||
|
ss.setAttribute(attributeName, attributes[attributeName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss.rel = "stylesheet";
|
||||||
|
ss.href = href;
|
||||||
|
ss.media = "only x";
|
||||||
|
function ready(cb) {
|
||||||
|
if (doc.body) {
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
ready(cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ready(function () {
|
||||||
|
ref.parentNode.insertBefore(ss, before ? ref : ref.nextSibling);
|
||||||
|
});
|
||||||
|
var onloadcssdefined = function (cb) {
|
||||||
|
var resolvedHref = ss.href;
|
||||||
|
var i = sheets.length;
|
||||||
|
while (i--) {
|
||||||
|
if (sheets[i].href === resolvedHref) {
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTimeout(function () {
|
||||||
|
onloadcssdefined(cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
function loadCB() {
|
||||||
|
if (ss.addEventListener) {
|
||||||
|
ss.removeEventListener("load", loadCB);
|
||||||
|
}
|
||||||
|
ss.media = media || "all";
|
||||||
|
}
|
||||||
|
if (ss.addEventListener) {
|
||||||
|
ss.addEventListener("load", loadCB);
|
||||||
|
}
|
||||||
|
ss.onloadcssdefined = onloadcssdefined;
|
||||||
|
onloadcssdefined(loadCB);
|
||||||
|
return ss;
|
||||||
|
},
|
||||||
|
|
||||||
|
js: (src, opt) => new Promise((resolve, reject) => {
|
||||||
|
var script = document.createElement('script');
|
||||||
|
if (src.startsWith('/')){
|
||||||
|
src = ctx.root + src.substring(1);
|
||||||
|
}
|
||||||
|
script.src = src;
|
||||||
|
if (opt) {
|
||||||
|
for (let key of Object.keys(opt)) {
|
||||||
|
script[key] = opt[key]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 默认异步,如果需要同步,第二个参数传入 {} 即可
|
||||||
|
script.async = true
|
||||||
|
}
|
||||||
|
script.onerror = reject
|
||||||
|
script.onload = script.onreadystatechange = function() {
|
||||||
|
const loadState = this.readyState
|
||||||
|
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
||||||
|
script.onload = script.onreadystatechange = null
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
document.head.appendChild(script)
|
||||||
|
}),
|
||||||
|
|
||||||
|
jq: (fn) => {
|
||||||
|
if (typeof jQuery === 'undefined') {
|
||||||
|
utils.js(deps.jquery).then(fn)
|
||||||
|
} else {
|
||||||
|
fn()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoading: (el) => {
|
||||||
|
if (el) {
|
||||||
|
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoadSuccess: (el) => {
|
||||||
|
if (el) {
|
||||||
|
$(el).find('.loading-wrap').remove();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoadFailure: (el) => {
|
||||||
|
if (el) {
|
||||||
|
$(el).find('.loading-wrap svg').remove();
|
||||||
|
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
||||||
|
$(el).find('.loading-wrap').addClass('error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
request: (el, url, callback, onFailure) => {
|
||||||
|
let retryTimes = 3;
|
||||||
|
utils.onLoading(el);
|
||||||
|
function req() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let status = 0; // 0 等待 1 完成 2 超时
|
||||||
|
let timer = setTimeout(() => {
|
||||||
|
if (status === 0) {
|
||||||
|
status = 2;
|
||||||
|
timer = null;
|
||||||
|
reject('请求超时');
|
||||||
|
if (retryTimes == 0) {
|
||||||
|
onFailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
fetch(url).then(function(response) {
|
||||||
|
if (status !== 2) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
resolve(response);
|
||||||
|
timer = null;
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw new Error('Network response was not ok.');
|
||||||
|
}).then(function(data) {
|
||||||
|
retryTimes = 0;
|
||||||
|
utils.onLoadSuccess(el);
|
||||||
|
callback(data);
|
||||||
|
}).catch(function(error) {
|
||||||
|
if (retryTimes > 0) {
|
||||||
|
retryTimes -= 1;
|
||||||
|
setTimeout(() => {
|
||||||
|
req();
|
||||||
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
utils.onLoadFailure(el);
|
||||||
|
onFailure();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
req();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
window.codeElements = document.querySelectorAll('.code');
|
||||||
|
if (window.codeElements.length > 0) {
|
||||||
|
ctx.copycode = {
|
||||||
|
default_text: `<%- conf.default_text %>`,
|
||||||
|
success_text: `<%- conf.success_text %>`,
|
||||||
|
toast: `<%- conf.toast %>`,
|
||||||
|
};
|
||||||
|
utils.js('/js/plugins/copycode.js');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
ctx.fancybox = {
|
||||||
|
selector: `<%- conf.selector %>`,
|
||||||
|
css: `<%- conf.css %>`,
|
||||||
|
js: `<%- conf.js %>`
|
||||||
|
};
|
||||||
|
var selector = '[data-fancybox]:not(.error)';
|
||||||
|
if (ctx.fancybox.selector) {
|
||||||
|
selector += `, ${ctx.fancybox.selector}`
|
||||||
|
}
|
||||||
|
var needFancybox = document.querySelectorAll(selector).length !== 0;
|
||||||
|
if (!needFancybox) {
|
||||||
|
const els = document.getElementsByClassName('stellar-memos-api');
|
||||||
|
if (els != undefined && els.length > 0) {
|
||||||
|
needFancybox = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needFancybox) {
|
||||||
|
utils.css(ctx.fancybox.css);
|
||||||
|
utils.js(ctx.fancybox.js, { defer: true }).then(function () {
|
||||||
|
Fancybox.bind(selector, {
|
||||||
|
hideScrollbar: false,
|
||||||
|
Thumbs: {
|
||||||
|
autoStart: false,
|
||||||
|
},
|
||||||
|
caption: (fancybox, slide) => {
|
||||||
|
return slide.triggerEl.alt || null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script>
|
||||||
|
utils.css(`<%- conf.css %>`);
|
||||||
|
utils.js(`<%- conf.js %>`, { defer: true }).then(function () {
|
||||||
|
const heti = new Heti('.heti');
|
||||||
|
|
||||||
|
// Copied from heti.autoSpacing() without DOMContentLoaded.
|
||||||
|
// https://github.com/sivan/heti/blob/eadee6a3b748b3b7924a9e7d5b395d4bce479c9a/js/heti-addon.js
|
||||||
|
//
|
||||||
|
// We managed to minimize the code modification to ensure .autoSpacing()
|
||||||
|
// is synced with upstream; therefore, we use `.bind()` to emulate the
|
||||||
|
// behavior of .autoSpacing() so we can even modify almost no code.
|
||||||
|
void (function () {
|
||||||
|
const $$rootList = document.querySelectorAll(this.rootSelector)
|
||||||
|
|
||||||
|
for (let $$root of $$rootList) {
|
||||||
|
this.spacingElement($$root)
|
||||||
|
}
|
||||||
|
}).bind(heti)();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<%
|
||||||
|
function loadPlugins() {
|
||||||
|
var el = ''
|
||||||
|
|
||||||
|
// search
|
||||||
|
if (theme.search[theme.search.service]) {
|
||||||
|
el += partial(`search/${theme.search.service}`, {conf: theme.search[theme.search.service]});
|
||||||
|
}
|
||||||
|
|
||||||
|
// others
|
||||||
|
for (let id of Object.keys(theme.plugins)) {
|
||||||
|
const conf = Object.assign({}, theme.plugins[id], page[id])
|
||||||
|
if (page[id] == true || conf.enable) {
|
||||||
|
if (conf.inject?.length > 0) {
|
||||||
|
el += conf.inject
|
||||||
|
} else {
|
||||||
|
el += partial(`${id}`, {conf: conf})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
<%- loadPlugins() %>
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script defer src="<%- conf.js %>"></script>
|
||||||
|
<script>
|
||||||
|
// https://www.npmjs.com/package/vanilla-lazyload
|
||||||
|
// Set the options globally
|
||||||
|
// to make LazyLoad self-initialize
|
||||||
|
window.lazyLoadOptions = {
|
||||||
|
elements_selector: ".lazy",
|
||||||
|
};
|
||||||
|
// Listen to the initialization event
|
||||||
|
// and get the instance of LazyLoad
|
||||||
|
window.addEventListener(
|
||||||
|
"LazyLoad::Initialized",
|
||||||
|
function (event) {
|
||||||
|
window.lazyLoadInstance = event.detail.instance;
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
window.lazyLoadInstance?.update();
|
||||||
|
});
|
||||||
|
</script>
|
2
layout/_partial/plugins/parser/mathjax/script.ejs → layout/_plugins/mathjax.ejs
Executable file → Normal file
2
layout/_partial/plugins/parser/mathjax/script.ejs → layout/_plugins/mathjax.ejs
Executable file → Normal file
|
@ -1,4 +1,4 @@
|
||||||
<script type="text/javascript" src="<%- theme.plugins.mathjax.js %>"></script>
|
<script type="text/javascript" src="<%- conf.js %>"></script>
|
||||||
<script type="text/x-mathjax-config">
|
<script type="text/x-mathjax-config">
|
||||||
MathJax.Hub.Config({
|
MathJax.Hub.Config({
|
||||||
tex2jax: {
|
tex2jax: {
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script defer type="text/javascript" src="<%- conf.js %>"></script>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
var mermaid_config = {
|
||||||
|
startOnLoad: true,
|
||||||
|
theme:
|
||||||
|
"<%- theme.style.darkmode %>" == "auto" &&
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
|
? "dark"
|
||||||
|
: "<%- conf.theme %>",
|
||||||
|
logLevel: 3,
|
||||||
|
themeVariables: {
|
||||||
|
darkMode: true
|
||||||
|
},
|
||||||
|
flowchart: {
|
||||||
|
useMaxWidth: false,
|
||||||
|
htmlLabels: true,
|
||||||
|
curve: "linear"
|
||||||
|
},
|
||||||
|
gantt: {
|
||||||
|
axisFormat: "%Y/%m/%d"
|
||||||
|
},
|
||||||
|
sequence: {
|
||||||
|
actorMargin: 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mermaid.initialize(mermaid_config);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<script>
|
||||||
|
window.FPConfig = {
|
||||||
|
delay: 0,
|
||||||
|
ignoreKeywords: [],
|
||||||
|
maxRPS: 5,
|
||||||
|
hoverDelay: 25
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script defer src="<%- conf.flying_pages %>"></script>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script defer src="<%- conf.js %>"></script>
|
||||||
|
<script>
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
const slideUp = {
|
||||||
|
distance: `<%- conf.distance %>`,
|
||||||
|
duration: `<%- conf.duration %>`,
|
||||||
|
interval: `<%- conf.interval %>`,
|
||||||
|
scale: `<%- conf.scale %>`,
|
||||||
|
opacity: 0,
|
||||||
|
easing: "ease-out"
|
||||||
|
};
|
||||||
|
ScrollReveal().reveal('.l_left .slide-up', slideUp);
|
||||||
|
ScrollReveal().reveal('.l_main .slide-up', slideUp);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<script>
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
ctx.search = {
|
||||||
|
path: `<%- conf.path || '/search.json' %>`,
|
||||||
|
}
|
||||||
|
utils.js('/js/search/local-search.js', { defer: true });
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<script>
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
const swiper_api = document.getElementById('swiper-api');
|
||||||
|
if (swiper_api != undefined) {
|
||||||
|
utils.css(`<%- conf.css %>`);
|
||||||
|
utils.js(`<%- conf.js %>`, { defer: true }).then(function () {
|
||||||
|
const effect = swiper_api.getAttribute('effect') || '';
|
||||||
|
var swiper = new Swiper('.swiper#swiper-api', {
|
||||||
|
slidesPerView: 'auto',
|
||||||
|
spaceBetween: 8,
|
||||||
|
centeredSlides: true,
|
||||||
|
effect: effect,
|
||||||
|
loop: true,
|
||||||
|
pagination: {
|
||||||
|
el: '.swiper-pagination',
|
||||||
|
clickable: true,
|
||||||
|
},
|
||||||
|
navigation: {
|
||||||
|
nextEl: '.swiper-button-next',
|
||||||
|
prevEl: '.swiper-button-prev',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<% if (['all', page.layout].includes(theme.plugins.tianli_gpt.field)) { %>
|
||||||
|
<script>
|
||||||
|
let tianliGPT_postSelector = 'article.content';
|
||||||
|
let tianliGPT_key = `<%= theme.plugins.tianli_gpt?.api %>`;
|
||||||
|
let tianliGPT_typingAnimate = `<%= theme.plugins.tianli_gpt?.typingAnimate %>`;
|
||||||
|
let tianliGPT_wordLimit = `<%= theme.plugins.tianli_gpt?.limit %>`;
|
||||||
|
</script>
|
||||||
|
<script defer src="<%- theme.plugins.tianli_gpt?.js %>"></script>
|
||||||
|
<% } %>
|
|
@ -42,7 +42,7 @@ html += `<html lang="${page.lang}">`
|
||||||
html += `<body>`
|
html += `<body>`
|
||||||
html += site_background
|
html += site_background
|
||||||
html += partial('_partial/cover/index')
|
html += partial('_partial/cover/index')
|
||||||
html += `<div class="l_body ${page_type} ${article_type}" id="start" layout="${page.layout}" ${indent ? 'text-indent' : ''}>`
|
html += `<div class="l_body s:aa ${page_type} ${article_type}" id="start" layout="${page.layout}" ${indent ? 'text-indent' : ''}>`
|
||||||
html += `<aside class="l_left">`
|
html += `<aside class="l_left">`
|
||||||
html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
|
html += `<div class="leftbar-container${theme.style.leftbar?.blur ? ' leftbar-blur' : ''}">`
|
||||||
html += partial('_partial/sidebar/index_leftbar')
|
html += partial('_partial/sidebar/index_leftbar')
|
||||||
|
@ -60,7 +60,7 @@ html += `<html lang="${page.lang}">`
|
||||||
html += partial('_partial/menubtn')
|
html += partial('_partial/menubtn')
|
||||||
html += `</div>`
|
html += `</div>`
|
||||||
html += `<div class="scripts">`
|
html += `<div class="scripts">`
|
||||||
html += partial('_partial/scripts/index')
|
html += partial('_partial/scripts')
|
||||||
html += `</div>`
|
html += `</div>`
|
||||||
html += `</body>`
|
html += `</body>`
|
||||||
html += `</html>`
|
html += `</html>`
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<%
|
<%
|
||||||
const { layout } = page
|
const { layout } = page
|
||||||
// 是否使用 Heti 布局插件
|
// 是否使用 Heti 布局插件
|
||||||
const isUsingHeti = theme.plugins.heti && theme.plugins.heti.enable
|
const isUsingHeti = theme.plugins.heti?.enable
|
||||||
// 是否使用 TianliGPT 插件
|
|
||||||
const isUsingTianliGPT = theme.plugins.tianli_gpt.enable && ['all', page.layout].includes(theme.plugins.tianli_gpt.field)
|
|
||||||
|
|
||||||
// 默认的 menu_id
|
// 默认的 menu_id
|
||||||
if (page.menu_id == null) {
|
if (page.menu_id == null) {
|
||||||
|
@ -27,9 +25,6 @@ function articleClass() {
|
||||||
if (isUsingHeti) {
|
if (isUsingHeti) {
|
||||||
str += ' heti'
|
str += ' heti'
|
||||||
}
|
}
|
||||||
if (isUsingTianliGPT) {
|
|
||||||
str += ' '
|
|
||||||
}
|
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,13 +47,10 @@ function layoutDiv() {
|
||||||
if (layout === 'post' || page.wiki) {
|
if (layout === 'post' || page.wiki) {
|
||||||
el += partial('_partial/main/article/read_next')
|
el += partial('_partial/main/article/read_next')
|
||||||
}
|
}
|
||||||
if (isUsingTianliGPT) {
|
|
||||||
el += partial('_partial/plugins/ai/tianli_gpt')
|
|
||||||
}
|
|
||||||
if (layout === 'post') {
|
if (layout === 'post') {
|
||||||
el += partial('_partial/main/article/related_posts')
|
el += partial('_partial/main/article/related_posts')
|
||||||
}
|
}
|
||||||
el += partial('_partial/plugins/comments/layout')
|
el += partial('_partial/comments/layout')
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
|
|
@ -14,7 +14,7 @@ module.exports = ctx => function(args) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
const url = full_url_for(args.url)
|
const url = full_url_for(args.url)
|
||||||
args.api = ctx.theme.config.tag_plugins.linkcard.api
|
args.api = ctx.theme.config.services.siteinfo?.api
|
||||||
if (args.api) {
|
if (args.api) {
|
||||||
args.api = args.api.replace('${href}', url)
|
args.api = args.api.replace('${href}', url)
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,3 +101,7 @@ article.md-text.content+.related-wrap
|
||||||
position: relative
|
position: relative
|
||||||
svg.loading
|
svg.loading
|
||||||
top: 60px
|
top: 60px
|
||||||
|
iframe
|
||||||
|
border-radius: $border-card
|
||||||
|
border: none
|
||||||
|
width: 100%
|
|
@ -75,6 +75,8 @@
|
||||||
max-width: 100%
|
max-width: 100%
|
||||||
text-align: justify
|
text-align: justify
|
||||||
margin-top: .5rem
|
margin-top: .5rem
|
||||||
|
overflow: scroll
|
||||||
|
scrollbar(0,0)
|
||||||
.tab-pane
|
.tab-pane
|
||||||
&:not(.active)
|
&:not(.active)
|
||||||
display: none
|
display: none
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.md-text .tag-plugin.timeline
|
.tag-plugin.timeline
|
||||||
position: relative
|
position: relative
|
||||||
padding-left: 16px
|
padding-left: 16px
|
||||||
&:before
|
&:before
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
&:before
|
&:before
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
.md-text .tag-plugin.timeline .timenode
|
.tag-plugin.timeline .timenode
|
||||||
position: relative
|
position: relative
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
|
@ -31,12 +31,8 @@
|
||||||
&+.timenode
|
&+.timenode
|
||||||
margin-top: 1rem
|
margin-top: 1rem
|
||||||
&:hover .header
|
&:hover .header
|
||||||
p
|
span
|
||||||
color: var(--text-p1)
|
color: var(--text-p1)
|
||||||
.user-info
|
|
||||||
background: $color-theme
|
|
||||||
span
|
|
||||||
color: var(--card)
|
|
||||||
&:before
|
&:before
|
||||||
background: $color-theme
|
background: $color-theme
|
||||||
height: 16px
|
height: 16px
|
||||||
|
@ -49,17 +45,17 @@
|
||||||
position: relative
|
position: relative
|
||||||
margin: 0.25rem 0
|
margin: 0.25rem 0
|
||||||
font-size: $fs-13
|
font-size: $fs-13
|
||||||
|
a.user-info span
|
||||||
|
font-weight: 600
|
||||||
.user-info
|
.user-info
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
font-size: $fs-13
|
font-size: $fs-13
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
color: var(--text-p1)
|
color: var(--text-p1)
|
||||||
margin-right: 4px
|
margin-right: 8px
|
||||||
line-height: 1
|
line-height: 1
|
||||||
border-radius: 16px
|
border-radius: 16px
|
||||||
padding-right: 6px
|
|
||||||
trans2 color background
|
|
||||||
img
|
img
|
||||||
background: white
|
background: white
|
||||||
height: 16px
|
height: 16px
|
||||||
|
@ -67,19 +63,10 @@
|
||||||
display: inline
|
display: inline
|
||||||
margin: 0 4px 0 0
|
margin: 0 4px 0 0
|
||||||
object-fit: contain
|
object-fit: contain
|
||||||
&:hover
|
&,span
|
||||||
background: $color-hover
|
|
||||||
&,p
|
|
||||||
font-weight: 500
|
font-weight: 500
|
||||||
color: var(--text-p3)
|
color: var(--text-p3)
|
||||||
trans1 color
|
|
||||||
line-height: 1
|
line-height: 1
|
||||||
p
|
|
||||||
margin: 0 !important
|
|
||||||
font-size: $fs-13 !important
|
|
||||||
a
|
|
||||||
color: inherit
|
|
||||||
font-weight: inherit
|
|
||||||
&:before
|
&:before
|
||||||
content: ''
|
content: ''
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -112,11 +99,6 @@
|
||||||
width: 240px
|
width: 240px
|
||||||
|
|
||||||
.tag-plugin.timeline[api]
|
.tag-plugin.timeline[api]
|
||||||
&.stellar-fcircle-api .timenode:hover .header
|
|
||||||
.user-info
|
|
||||||
background: inherit
|
|
||||||
span
|
|
||||||
color: inherit
|
|
||||||
a.body
|
a.body
|
||||||
display: block
|
display: block
|
||||||
color: var(--text-p1)
|
color: var(--text-p1)
|
||||||
|
@ -187,6 +169,8 @@
|
||||||
flex-wrap: wrap
|
flex-wrap: wrap
|
||||||
font-size: $fs-13
|
font-size: $fs-13
|
||||||
align-items: stretch
|
align-items: stretch
|
||||||
|
.left+.right
|
||||||
|
margin-left: 4px
|
||||||
|
|
||||||
.tag-plugin.timeline[api] .body .footer
|
.tag-plugin.timeline[api] .body .footer
|
||||||
.item
|
.item
|
||||||
|
@ -202,8 +186,13 @@
|
||||||
margin-left: 0
|
margin-left: 0
|
||||||
&:last-child
|
&:last-child
|
||||||
margin-right: 0
|
margin-right: 0
|
||||||
a:hover
|
a.item
|
||||||
border-color: $color-hover
|
background: var(--block)
|
||||||
|
border-color: var(--block-border)
|
||||||
|
color: inherit
|
||||||
|
&:hover
|
||||||
|
background: var(--block-hover)
|
||||||
|
|
||||||
.reaction
|
.reaction
|
||||||
border-color: var(--block)
|
border-color: var(--block)
|
||||||
|
|
||||||
|
@ -237,8 +226,9 @@
|
||||||
p:last-child
|
p:last-child
|
||||||
margin-bottom: 2px
|
margin-bottom: 2px
|
||||||
img
|
img
|
||||||
margin: 0
|
margin: .5rem 0
|
||||||
max-height: 128px
|
max-height: 128px
|
||||||
|
cursor: zoom-in
|
||||||
.tag-plugin.image
|
.tag-plugin.image
|
||||||
display: flex
|
display: flex
|
||||||
.image-bg+.image-bg
|
.image-bg+.image-bg
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
.widget-wrapper.timeline
|
.widget-wrapper.timeline
|
||||||
|
.tag-plugin.timeline
|
||||||
|
padding-left: 0
|
||||||
|
&:before
|
||||||
|
left: 6px
|
||||||
.widget-body
|
.widget-body
|
||||||
overflow hidden
|
overflow hidden
|
||||||
.body
|
.body
|
||||||
|
@ -7,22 +11,23 @@
|
||||||
word-break: break-all
|
word-break: break-all
|
||||||
--fsp: $fsp2
|
--fsp: $fsp2
|
||||||
.tag-plugin.timeline .timenode
|
.tag-plugin.timeline .timenode
|
||||||
|
z-index 1
|
||||||
|
margin-top: 0.5rem
|
||||||
.header
|
.header
|
||||||
margin: 0.5rem var(--gap-padding)
|
margin: 0.25rem var(--gap-padding)
|
||||||
txt-ellipsis()
|
|
||||||
.user-info
|
.user-info
|
||||||
background: var(--alpha50)
|
background: none
|
||||||
&:hover
|
padding-right: 0
|
||||||
background: $color-hover
|
img
|
||||||
color: var(--card)
|
|
||||||
&:before
|
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
|
.header:before
|
||||||
|
left: calc(6px - var(--gap-padding))
|
||||||
&+.timenode
|
&+.timenode
|
||||||
margin-top: 0.75rem
|
margin-top: 0.75rem
|
||||||
.header p
|
|
||||||
color: var(--text-p2)
|
|
||||||
.body
|
.body
|
||||||
border-radius: $border-card
|
border-radius: $border-card
|
||||||
|
padding: 0.5rem 1rem
|
||||||
p,li
|
p,li
|
||||||
--fsp: $fsp3
|
--fsp: $fsp3
|
||||||
code
|
code
|
||||||
|
@ -35,10 +40,12 @@
|
||||||
|
|
||||||
.tag-plugin.timeline[api] .body .footer
|
.tag-plugin.timeline[api] .body .footer
|
||||||
background: none
|
background: none
|
||||||
a.item
|
|
||||||
border-color: var(--text)
|
|
||||||
|
|
||||||
|
|
||||||
|
.l_left .widget-wrapper.timeline
|
||||||
|
.tag-plugin.timeline
|
||||||
|
padding-left: 0
|
||||||
|
&:before
|
||||||
|
content: none
|
||||||
.l_left .widget-wrapper.timeline .body
|
.l_left .widget-wrapper.timeline .body
|
||||||
box-shadow: none
|
box-shadow: none
|
||||||
background: var(--alpha50)
|
background: var(--alpha50)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.widget-wrapper.toc
|
.widget-wrapper.toc
|
||||||
background: var(--site-bg)
|
background: var(--site-bg)
|
||||||
z-index 1
|
z-index 3
|
||||||
.widget-body
|
.widget-body
|
||||||
position relative
|
position relative
|
||||||
&:before
|
&:before
|
||||||
|
|
|
@ -19,13 +19,13 @@ const util = {
|
||||||
if (dayCount > 14) {
|
if (dayCount > 14) {
|
||||||
result = null
|
result = null
|
||||||
} else if (dayCount >= 1) {
|
} else if (dayCount >= 1) {
|
||||||
result = parseInt(dayCount) + ' ' + stellar.config.date_suffix.day
|
result = parseInt(dayCount) + ' ' + ctx.date_suffix.day
|
||||||
} else if (hourCount >= 1) {
|
} else if (hourCount >= 1) {
|
||||||
result = parseInt(hourCount) + ' ' + stellar.config.date_suffix.hour
|
result = parseInt(hourCount) + ' ' + ctx.date_suffix.hour
|
||||||
} else if (minuteCount >= 1) {
|
} else if (minuteCount >= 1) {
|
||||||
result = parseInt(minuteCount) + ' ' + stellar.config.date_suffix.min
|
result = parseInt(minuteCount) + ' ' + ctx.date_suffix.min
|
||||||
} else {
|
} else {
|
||||||
result = stellar.config.date_suffix.just
|
result = ctx.date_suffix.just
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = parseInt(dateDiff / day)
|
result = parseInt(dateDiff / day)
|
||||||
|
@ -75,33 +75,10 @@ const hud = {
|
||||||
|
|
||||||
const l_body = document.querySelector('.l_body');
|
const l_body = document.querySelector('.l_body');
|
||||||
|
|
||||||
const sidebar = {
|
|
||||||
leftbar: () => {
|
|
||||||
if (l_body) {
|
|
||||||
l_body.toggleAttribute('leftbar');
|
|
||||||
l_body.removeAttribute('rightbar');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rightbar: () => {
|
|
||||||
if (l_body) {
|
|
||||||
l_body.toggleAttribute('rightbar');
|
|
||||||
l_body.removeAttribute('leftbar');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dismiss: () => {
|
|
||||||
if (l_body) {
|
|
||||||
l_body.removeAttribute('leftbar');
|
|
||||||
l_body.removeAttribute('rightbar');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleTOC: () => {
|
|
||||||
document.querySelector('#data-toc').classList.toggle('collapse');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const init = {
|
const init = {
|
||||||
toc: () => {
|
toc: () => {
|
||||||
stellar.jQuery(() => {
|
utils.jq(() => {
|
||||||
const scrollOffset = 32;
|
const scrollOffset = 32;
|
||||||
var segs = [];
|
var segs = [];
|
||||||
$("article.md-text :header").each(function (idx, node) {
|
$("article.md-text :header").each(function (idx, node) {
|
||||||
|
@ -160,7 +137,7 @@ const init = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
sidebar: () => {
|
sidebar: () => {
|
||||||
stellar.jQuery(() => {
|
utils.jq(() => {
|
||||||
$("#data-toc a.toc-link").click(function (e) {
|
$("#data-toc a.toc-link").click(function (e) {
|
||||||
sidebar.dismiss();
|
sidebar.dismiss();
|
||||||
});
|
});
|
||||||
|
@ -213,203 +190,3 @@ init.toc()
|
||||||
init.sidebar()
|
init.sidebar()
|
||||||
init.relativeDate(document.querySelectorAll('#post-meta time'))
|
init.relativeDate(document.querySelectorAll('#post-meta time'))
|
||||||
init.registerTabsTag()
|
init.registerTabsTag()
|
||||||
|
|
||||||
// scrollreveal
|
|
||||||
if (stellar.plugins.scrollreveal) {
|
|
||||||
stellar.loadScript(stellar.plugins.scrollreveal.js).then(function () {
|
|
||||||
const slideUp = {
|
|
||||||
distance: stellar.plugins.scrollreveal.distance,
|
|
||||||
duration: stellar.plugins.scrollreveal.duration,
|
|
||||||
interval: stellar.plugins.scrollreveal.interval,
|
|
||||||
scale: stellar.plugins.scrollreveal.scale,
|
|
||||||
opacity: 0,
|
|
||||||
easing: "ease-out"
|
|
||||||
}
|
|
||||||
ScrollReveal().reveal('.l_left .slide-up', slideUp)
|
|
||||||
ScrollReveal().reveal('.l_main .slide-up', slideUp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// lazyload
|
|
||||||
if (stellar.plugins.lazyload) {
|
|
||||||
stellar.loadScript(stellar.plugins.lazyload.js, { defer: true })
|
|
||||||
// https://www.npmjs.com/package/vanilla-lazyload
|
|
||||||
// Set the options globally
|
|
||||||
// to make LazyLoad self-initialize
|
|
||||||
window.lazyLoadOptions = {
|
|
||||||
elements_selector: ".lazy",
|
|
||||||
};
|
|
||||||
// Listen to the initialization event
|
|
||||||
// and get the instance of LazyLoad
|
|
||||||
window.addEventListener(
|
|
||||||
"LazyLoad::Initialized",
|
|
||||||
function (event) {
|
|
||||||
window.lazyLoadInstance = event.detail.instance;
|
|
||||||
},
|
|
||||||
false
|
|
||||||
);
|
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
|
||||||
window.lazyLoadInstance?.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// stellar js
|
|
||||||
if (stellar.plugins.stellar) {
|
|
||||||
for (let key of Object.keys(stellar.plugins.stellar)) {
|
|
||||||
let js = stellar.plugins.stellar[key];
|
|
||||||
if (key == 'linkcard') {
|
|
||||||
stellar.loadScript(js, { defer: true }).then(function () {
|
|
||||||
setCardLink(document.querySelectorAll('a.link-card[cardlink]'));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const els = document.getElementsByClassName('stellar-' + key + '-api');
|
|
||||||
if (els != undefined && els.length > 0) {
|
|
||||||
stellar.jQuery(() => {
|
|
||||||
if (key == 'timeline' || 'memos' || 'marked') {
|
|
||||||
stellar.loadScript(stellar.plugins.marked).then(function () {
|
|
||||||
stellar.loadScript(js, { defer: true });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
stellar.loadScript(js, { defer: true });
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiper
|
|
||||||
if (stellar.plugins.swiper) {
|
|
||||||
const swiper_api = document.getElementById('swiper-api');
|
|
||||||
if (swiper_api != undefined) {
|
|
||||||
stellar.loadCSS(stellar.plugins.swiper.css);
|
|
||||||
stellar.loadScript(stellar.plugins.swiper.js, { defer: true }).then(function () {
|
|
||||||
const effect = swiper_api.getAttribute('effect') || '';
|
|
||||||
var swiper = new Swiper('.swiper#swiper-api', {
|
|
||||||
slidesPerView: 'auto',
|
|
||||||
spaceBetween: 8,
|
|
||||||
centeredSlides: true,
|
|
||||||
effect: effect,
|
|
||||||
loop: true,
|
|
||||||
pagination: {
|
|
||||||
el: '.swiper-pagination',
|
|
||||||
clickable: true,
|
|
||||||
},
|
|
||||||
navigation: {
|
|
||||||
nextEl: '.swiper-button-next',
|
|
||||||
prevEl: '.swiper-button-prev',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// preload
|
|
||||||
if (stellar.plugins.preload) {
|
|
||||||
if (stellar.plugins.preload.service == 'flying_pages') {
|
|
||||||
window.FPConfig = {
|
|
||||||
delay: 0,
|
|
||||||
ignoreKeywords: [],
|
|
||||||
maxRPS: 5,
|
|
||||||
hoverDelay: 25
|
|
||||||
};
|
|
||||||
stellar.loadScript(stellar.plugins.preload.flying_pages, { defer: true })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fancybox
|
|
||||||
if (stellar.plugins.fancybox) {
|
|
||||||
let selector = '[data-fancybox]:not(.error)';
|
|
||||||
if (stellar.plugins.fancybox.selector) {
|
|
||||||
selector += `, ${stellar.plugins.fancybox.selector}`
|
|
||||||
}
|
|
||||||
var needFancybox = document.querySelectorAll(selector).length !== 0;
|
|
||||||
if (!needFancybox) {
|
|
||||||
const els = document.getElementsByClassName('stellar-memos-api');
|
|
||||||
if (els != undefined && els.length > 0) {
|
|
||||||
needFancybox = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needFancybox) {
|
|
||||||
stellar.loadCSS(stellar.plugins.fancybox.css);
|
|
||||||
stellar.loadScript(stellar.plugins.fancybox.js, { defer: true }).then(function () {
|
|
||||||
Fancybox.bind(selector, {
|
|
||||||
hideScrollbar: false,
|
|
||||||
Thumbs: {
|
|
||||||
autoStart: false,
|
|
||||||
},
|
|
||||||
caption: (fancybox, slide) => {
|
|
||||||
return slide.triggerEl.alt || null
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (stellar.search.service) {
|
|
||||||
if (stellar.search.service == 'local_search') {
|
|
||||||
stellar.jQuery(() => {
|
|
||||||
stellar.loadScript('/js/search/local-search.js', { defer: true }).then(function () {
|
|
||||||
var $inputArea = $("input#search-input");
|
|
||||||
if ($inputArea.length == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var $resultArea = document.querySelector("div#search-result");
|
|
||||||
$inputArea.focus(function() {
|
|
||||||
var path = stellar.search[stellar.search.service]?.path || '/search.json';
|
|
||||||
if (path.startsWith('/')) {
|
|
||||||
path = path.substring(1);
|
|
||||||
}
|
|
||||||
path = stellar.config.root + path;
|
|
||||||
const filter = $inputArea.attr('data-filter') || '';
|
|
||||||
searchFunc(path, filter, 'search-wrapper', 'search-input', 'search-result');
|
|
||||||
});
|
|
||||||
$inputArea.keydown(function(e) {
|
|
||||||
if (e.which == 13) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var observer = new MutationObserver(function(mutationsList, observer) {
|
|
||||||
if (mutationsList.length == 1) {
|
|
||||||
if (mutationsList[0].addedNodes.length) {
|
|
||||||
$('.search-wrapper').removeClass('noresult');
|
|
||||||
} else if (mutationsList[0].removedNodes.length) {
|
|
||||||
$('.search-wrapper').addClass('noresult');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
observer.observe($resultArea, { childList: true });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// heti
|
|
||||||
if (stellar.plugins.heti) {
|
|
||||||
stellar.loadCSS(stellar.plugins.heti.css);
|
|
||||||
stellar.loadScript(stellar.plugins.heti.js, { defer: true }).then(function () {
|
|
||||||
const heti = new Heti('.heti');
|
|
||||||
|
|
||||||
// Copied from heti.autoSpacing() without DOMContentLoaded.
|
|
||||||
// https://github.com/sivan/heti/blob/eadee6a3b748b3b7924a9e7d5b395d4bce479c9a/js/heti-addon.js
|
|
||||||
//
|
|
||||||
// We managed to minimize the code modification to ensure .autoSpacing()
|
|
||||||
// is synced with upstream; therefore, we use `.bind()` to emulate the
|
|
||||||
// behavior of .autoSpacing() so we can even modify almost no code.
|
|
||||||
void (function () {
|
|
||||||
const $$rootList = document.querySelectorAll(this.rootSelector)
|
|
||||||
|
|
||||||
for (let $$root of $$rootList) {
|
|
||||||
this.spacingElement($$root)
|
|
||||||
}
|
|
||||||
}).bind(heti)();
|
|
||||||
|
|
||||||
stellar.plugins.heti.enable = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stellar.plugins.copycode) {
|
|
||||||
stellar.loadScript(stellar.plugins.copycode.js, { defer: true })
|
|
||||||
}
|
|
|
@ -1,45 +1,41 @@
|
||||||
const codeElementArr = document.querySelectorAll('.code')
|
window.codeElements.forEach(code => {
|
||||||
codeElementArr.forEach(code => {
|
|
||||||
// copy btn
|
// copy btn
|
||||||
const codeCopyBtn = document.createElement('div')
|
const codeCopyBtn = document.createElement('div');
|
||||||
codeCopyBtn.classList.add('copy-btn')
|
codeCopyBtn.classList.add('copy-btn');
|
||||||
codeCopyBtn.innerHTML = stellar.plugins.copycode.default_text
|
codeCopyBtn.innerHTML = ctx.copycode.default_text;
|
||||||
|
code.appendChild(codeCopyBtn);
|
||||||
code.appendChild(codeCopyBtn)
|
|
||||||
|
|
||||||
codeCopyBtn.addEventListener('click', async () => {
|
codeCopyBtn.addEventListener('click', async () => {
|
||||||
const currentCodeElement = code.children[0]?.innerText
|
const currentCodeElement = code.children[0]?.innerText;
|
||||||
await copyCode(currentCodeElement)
|
await copyCode(currentCodeElement);
|
||||||
|
codeCopyBtn.innerHTML = ctx.copycode.success_text;
|
||||||
codeCopyBtn.innerHTML = stellar.plugins.copycode.success_text
|
codeCopyBtn.classList.add('success');
|
||||||
codeCopyBtn.classList.add('success')
|
hud.toast(ctx.copycode.toast, 2500);
|
||||||
hud.toast(stellar.plugins.copycode.toast, 2500)
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
codeCopyBtn.innerHTML = stellar.plugins.copycode.default_text
|
codeCopyBtn.innerHTML = ctx.copycode.default_text;
|
||||||
codeCopyBtn.classList.remove('success')
|
codeCopyBtn.classList.remove('success');
|
||||||
},3000)
|
},3000);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function copyCode(currentCode) {
|
async function copyCode(currentCode) {
|
||||||
if (navigator.clipboard) {
|
if (navigator.clipboard) {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(currentCode)
|
await navigator.clipboard.writeText(currentCode);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 未获得用户许可
|
// 未获得用户许可
|
||||||
codeCopyBtn.innerText = '未获得用户许可'
|
codeCopyBtn.innerText = '未获得用户许可';
|
||||||
codeCopyBtn.classList.add('warning')
|
codeCopyBtn.classList.add('warning');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
|
codeCopyBtn.innerText = ctx.copycode.default_text;
|
||||||
codeCopyBtn.classList.remove('warning')
|
codeCopyBtn.classList.remove('warning');
|
||||||
},3000)
|
},3000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
codeCopyBtn.innerText = '当前浏览器不支持此api'
|
codeCopyBtn.innerText = '当前浏览器不支持此api';
|
||||||
codeCopyBtn.classList.add('warning')
|
codeCopyBtn.classList.add('warning');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
codeCopyBtn.innerText = stellar.plugins.copycode.default_text
|
codeCopyBtn.innerText = ctx.copycode.default_text;
|
||||||
codeCopyBtn.classList.remove('warning')
|
codeCopyBtn.classList.remove('warning');
|
||||||
},3000)
|
},3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,92 +0,0 @@
|
||||||
const FCircle = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layoutDiv: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
FCircle.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
const arr = data.article_data || [];
|
|
||||||
const limit = el.getAttribute('limit');
|
|
||||||
arr.forEach((item, i) => {
|
|
||||||
if (limit && i >= limit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var cell = '<div class="timenode" index="' + i + '">';
|
|
||||||
cell += '<div class="header">';
|
|
||||||
cell += '<div class="user-info">';
|
|
||||||
cell += '<img src="' + (item.avatar || cfg.avatar) + '" onerror="javascript:this.src=\'' + cfg.avatar + '\';">';
|
|
||||||
cell += '<span>' + item.author + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<span>' + item.created + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<a class="body" href="' + item.link + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += item.title;
|
|
||||||
cell += '</a>';
|
|
||||||
cell += '</div>';
|
|
||||||
$(el).append(cell);
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-fcircle-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.avatar = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/avatar/round/3442075.svg';
|
|
||||||
FCircle.layoutDiv(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,84 +0,0 @@
|
||||||
const friendsjs = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layout: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
friendsjs.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
for (let item of (data.content || data)) {
|
|
||||||
var cell = `<div class="grid-cell user-card">`;
|
|
||||||
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.html_url || item.url}">`;;
|
|
||||||
cell += `<img src="${item.avatar_url || item.avatar || item.icon || cfg.avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${cfg.avatar}\';"/>`;
|
|
||||||
cell += `<div class="name image-meta">`;
|
|
||||||
cell += `<span class="image-caption">${item.title || item.login}</span>`;
|
|
||||||
cell += `</div>`;
|
|
||||||
cell += `</a>`;
|
|
||||||
cell += `</div>`;
|
|
||||||
$(el).find('.grid-box').append(cell);
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-friends-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.class = el.getAttribute('class');
|
|
||||||
cfg.avatar = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/avatar/round/3442075.svg';
|
|
||||||
friendsjs.layout(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,85 +0,0 @@
|
||||||
const GitHubInfo = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layout: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
function fill(data) {
|
|
||||||
for (let key of Object.keys(data)) {
|
|
||||||
$(el).find("[type=text]#" + key).text(data[key]);
|
|
||||||
$(el).find("[type=link]#" + key).attr("href", data[key]);
|
|
||||||
$(el).find("[type=img]#" + key).attr("src", data[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GitHubInfo.requestAPI(cfg.api, function(data) {
|
|
||||||
const idx = el.getAttribute('index');
|
|
||||||
if (idx != undefined) {
|
|
||||||
const arr = data.content || data;
|
|
||||||
if (arr && arr.length > idx) {
|
|
||||||
let obj = arr[idx];
|
|
||||||
obj['latest-tag-name'] = obj['name'];
|
|
||||||
fill(arr[idx]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fill(data);
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-ghinfo-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.class = el.getAttribute('class');
|
|
||||||
GitHubInfo.layout(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,48 +0,0 @@
|
||||||
// 本插件由CardLink定制而成,原项目源码: https://github.com/Lete114/CardLink
|
|
||||||
|
|
||||||
function renderer(el, obj) {
|
|
||||||
var autofill = [];
|
|
||||||
const autofillStr = el.getAttribute('autofill');
|
|
||||||
if (autofillStr) {
|
|
||||||
autofill = autofillStr.split(',');
|
|
||||||
}
|
|
||||||
if (obj.title && obj.title.length > 0 && autofill.includes('title')) {
|
|
||||||
el.querySelector('.title').innerHTML = obj.title;
|
|
||||||
el.title = obj.title;
|
|
||||||
}
|
|
||||||
if (obj.icon && obj.icon.length > 0 && autofill.includes('icon')) {
|
|
||||||
el.querySelector('.img').style = 'background-image: url("' + obj.icon + '");';
|
|
||||||
el.querySelector('.img').setAttribute('data-bg', obj.icon);
|
|
||||||
}
|
|
||||||
let desc = el.querySelector('.desc');
|
|
||||||
if (desc && obj.desc && obj.desc.length > 0 && autofill.includes('desc')) {
|
|
||||||
desc.innerHTML = obj.desc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create card links
|
|
||||||
* @param {NodeList} nodes A collection of nodes or a collection of arrays,
|
|
||||||
* if it is an array then the array must always contain node element
|
|
||||||
*/
|
|
||||||
function setCardLink(nodes) {
|
|
||||||
// If the `nodes` do not contain a `forEach` method, then the default `a[cardlink]` is used
|
|
||||||
nodes = 'forEach' in (nodes || {}) ? nodes : document.querySelectorAll('a[cardlink]')
|
|
||||||
nodes.forEach((el) => {
|
|
||||||
// If it is not a tag element then it is not processed
|
|
||||||
if (el.nodeType !== 1) return;
|
|
||||||
el.removeAttribute('cardlink');
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) return;
|
|
||||||
fetch(api).then(function(response) {
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
renderer(el, data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
const loadMarkdown = (cfg) => {
|
|
||||||
if (!window.fetch) {
|
|
||||||
cfg.el.innerHTML =
|
|
||||||
'<div style="font-size: 24px"><p>Your browser outdated. Please use the latest version of Chrome or Firefox!</p><p>您的浏览器版本过低,请使用最新版的 Chrome 或 Firefox 浏览器!</p></div>';
|
|
||||||
} else {
|
|
||||||
cfg.el.innerHTML =
|
|
||||||
'<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>';
|
|
||||||
fetch(cfg.src, { method: "GET" })
|
|
||||||
.then((resp) => {
|
|
||||||
return Promise.all([
|
|
||||||
resp.ok,
|
|
||||||
resp.status,
|
|
||||||
resp.text(),
|
|
||||||
resp.headers,
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
.then(([ok, status, data, headers]) => {
|
|
||||||
if (ok) {
|
|
||||||
return {
|
|
||||||
ok,
|
|
||||||
status,
|
|
||||||
data,
|
|
||||||
headers,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new Error(JSON.stringify(json.error));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then((resp) => {
|
|
||||||
let data = marked.parse(resp.data);
|
|
||||||
cfg.el.innerHTML = data;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
cfg.el.innerHTML =
|
|
||||||
'<div class="loading-wrap error"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg></div>';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-marked-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
var cfg = new Object();
|
|
||||||
const el = els[i];
|
|
||||||
cfg.src = `${el.getAttribute('src')}?t=${new Date().getTime()}`;
|
|
||||||
cfg.el = el;
|
|
||||||
loadMarkdown(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,132 +0,0 @@
|
||||||
const MemosJS = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layoutDiv: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
MemosJS.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
var users = [];
|
|
||||||
const filter = el.getAttribute('user');
|
|
||||||
if (filter && filter.length > 0) {
|
|
||||||
users = filter.split(",");
|
|
||||||
}
|
|
||||||
var hide = [];
|
|
||||||
const hideStr = el.getAttribute('hide');
|
|
||||||
if (hideStr && hideStr.length > 0) {
|
|
||||||
hide = hideStr.split(",");
|
|
||||||
}
|
|
||||||
data.forEach((item, i) => {
|
|
||||||
if (cfg.limit && i >= cfg.limit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (item.user && item.user.login && users.length > 0) {
|
|
||||||
if (!users.includes(item.user.login)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let date = new Date(item.createdTs * 1000)
|
|
||||||
var cell = '<div class="timenode" index="' + i + '">';
|
|
||||||
cell += '<div class="header">';
|
|
||||||
if (!users.length && !hide.includes('user')) {
|
|
||||||
cell += '<div class="user-info">';
|
|
||||||
if (cfg.avatar?.length > 0) {
|
|
||||||
cell += `<img src="${cfg.avatar}">`;
|
|
||||||
}
|
|
||||||
cell += '<span>' + item.creatorName + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
}
|
|
||||||
cell += '<span>' + date.toLocaleString() + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<div class="body">';
|
|
||||||
cell += marked.parse(item.content || '');
|
|
||||||
var imgs = [];
|
|
||||||
for (let res of item.resourceList) {
|
|
||||||
if (res.type?.includes('image/')) {
|
|
||||||
imgs.push(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (imgs.length > 0) {
|
|
||||||
cell += '<div class="tag-plugin image">';
|
|
||||||
for (let img of imgs) {
|
|
||||||
if (img.externalLink?.length > 0) {
|
|
||||||
cell += `<div class="image-bg"><img src="${img.externalLink}" data-fancybox="memos"></div>`;
|
|
||||||
} else {
|
|
||||||
cell += `<div class="image-bg"><img src="https://${cfg.host}/o/r/${img.id}" data-fancybox="memos"></div>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cell += '</div>';
|
|
||||||
}
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '</div>';
|
|
||||||
$(el).append(cell);
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-memos-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.limit = el.getAttribute('limit');
|
|
||||||
cfg.host = api.replace(/https:\/\/(.*?)\/(.*)/i, '$1');
|
|
||||||
cfg.avatar = el.getAttribute('avatar');
|
|
||||||
if (!cfg.avatar) {
|
|
||||||
cfg.avatar = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/avatar/round/3442075.svg';
|
|
||||||
}
|
|
||||||
MemosJS.layoutDiv(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,87 +0,0 @@
|
||||||
const sitesjs = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layout: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
sitesjs.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
for (let item of data.content) {
|
|
||||||
var cell = `<div class="grid-cell site-card">`;
|
|
||||||
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`;
|
|
||||||
cell += `<img src="${item.cover || item.screenshot}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${cfg.screenshot}\';"/>`;
|
|
||||||
cell += `<div class="info">`;
|
|
||||||
cell += `<img src="${item.icon || item.avatar || cfg.avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${cfg.avatar}\';"/>`;
|
|
||||||
cell += `<span class="title">${item.title}</span>`;
|
|
||||||
cell += `<span class="desc">${item.description || item.url}</span>`;
|
|
||||||
cell += `</div>`;
|
|
||||||
cell += `</a>`;
|
|
||||||
cell += `</div>`;
|
|
||||||
$(el).find('.grid-box').append(cell);
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-sites-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.class = el.getAttribute('class');
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.avatar = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/link/8f277b4ee0ecd.svg';
|
|
||||||
cfg.screenshot = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/cover/76b86c0226ffd.svg';
|
|
||||||
sitesjs.layout(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,162 +0,0 @@
|
||||||
const StellarTimeline = {
|
|
||||||
reactions: {
|
|
||||||
'+1': '👍',
|
|
||||||
'-1': '👎',
|
|
||||||
'laugh': '😀',
|
|
||||||
'hooray': '🎉',
|
|
||||||
'confused': '😕',
|
|
||||||
'heart': '❤️',
|
|
||||||
'rocket': '🚀',
|
|
||||||
'eyes': '👀'
|
|
||||||
},
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layoutDiv: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
StellarTimeline.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
const query = new URL(cfg.api).search;
|
|
||||||
const arr = data.content || data;
|
|
||||||
var users = [];
|
|
||||||
const filter = el.getAttribute('user');
|
|
||||||
if (filter && filter.length > 0) {
|
|
||||||
users = filter.split(",");
|
|
||||||
}
|
|
||||||
var hide = [];
|
|
||||||
const hideStr = el.getAttribute('hide');
|
|
||||||
if (hideStr && hideStr.length > 0) {
|
|
||||||
hide = hideStr.split(",");
|
|
||||||
}
|
|
||||||
arr.forEach((item, i) => {
|
|
||||||
if (item.user && item.user.login && users.length > 0) {
|
|
||||||
if (!users.includes(item.user.login)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var cell = '<div class="timenode" index="' + i + '">';
|
|
||||||
cell += '<div class="header">';
|
|
||||||
if (!users.length && item.user && !hide.includes('user')) {
|
|
||||||
cell += '<a class="user-info" href="' + item.user.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<img src="' + item.user.avatar_url + '">';
|
|
||||||
cell += '<span>' + item.user.login + '</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
}
|
|
||||||
let date = new Date(item.created_at);
|
|
||||||
cell += '<span>' + date.toLocaleString() + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<div class="body">';
|
|
||||||
if (!hide.includes('title')) {
|
|
||||||
cell += '<p class="title">';
|
|
||||||
cell += '<a href="' + item.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += item.title || item.name || item.tag_name;
|
|
||||||
cell += '</a>';
|
|
||||||
cell += '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
cell += marked.parse(item.body || '');
|
|
||||||
if (!hide.includes('footer')) {
|
|
||||||
cell += '<div class="footer">';
|
|
||||||
cell += '<div class="flex left">';
|
|
||||||
if (item.labels) {
|
|
||||||
item.labels.forEach((label, i) => {
|
|
||||||
if (!query || !query.includes(encodeURI(label.name))) {
|
|
||||||
cell += '<div class="item label ' + label.name + '" style="background:#' + label.color + '18;border-color:#' + label.color + '36">';
|
|
||||||
cell += '<span>' + label.name + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (item.zipball_url) {
|
|
||||||
cell += '<a class="item download" href="' + item.zipball_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<span>📦 ' + item.tag_name + '.zip</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
}
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<div class="flex right">';
|
|
||||||
if (item.reactions && item.reactions.total_count > 0) {
|
|
||||||
for (let key of Object.keys(StellarTimeline.reactions)) {
|
|
||||||
let num = item.reactions[key];
|
|
||||||
if (num > 0) {
|
|
||||||
cell += '<div class="item reaction ' + key + '">';
|
|
||||||
cell += '<span>' + StellarTimeline.reactions[key] + ' ' + item.reactions[key] + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (item.comments != null) {
|
|
||||||
cell += '<a class="item comments last" href="' + item.html_url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<span><svg t="1666270368054" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="200" height="200"><path d="M952 64H72C32.3 64 0 96.3 0 136v508c0 39.7 32.3 72 72 72h261l128 128c14 14 32.5 21.1 50.9 21.1s36.9-7 50.9-21.1l128-128h261c39.7 0 72-32.3 72-72V136c0.2-39.7-32.1-72-71.8-72zM222 462c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m290-7.7c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z m290 8c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z" p-id="2529"></path></svg> ' + (item.comments || 0) + '</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '</div>';
|
|
||||||
$(el).append(cell);
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-timeline-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api');
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var obj = new Object();
|
|
||||||
obj.el = el;
|
|
||||||
obj.api = api;
|
|
||||||
StellarTimeline.layoutDiv(obj);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,116 +0,0 @@
|
||||||
const weibojs = {
|
|
||||||
requestAPI: (url, callback, timeout) => {
|
|
||||||
let retryTimes = 5;
|
|
||||||
function request() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let status = 0; // 0 等待 1 完成 2 超时
|
|
||||||
let timer = setTimeout(() => {
|
|
||||||
if (status === 0) {
|
|
||||||
status = 2;
|
|
||||||
timer = null;
|
|
||||||
reject('请求超时');
|
|
||||||
if (retryTimes == 0) {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
fetch(url).then(function(response) {
|
|
||||||
if (status !== 2) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
resolve(response);
|
|
||||||
timer = null;
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw new Error('Network response was not ok.');
|
|
||||||
}).then(function(data) {
|
|
||||||
retryTimes = 0;
|
|
||||||
callback(data);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (retryTimes > 0) {
|
|
||||||
retryTimes -= 1;
|
|
||||||
setTimeout(() => {
|
|
||||||
request();
|
|
||||||
}, 5000);
|
|
||||||
} else {
|
|
||||||
timeout();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
request();
|
|
||||||
},
|
|
||||||
layoutDiv: (cfg) => {
|
|
||||||
const el = $(cfg.el)[0];
|
|
||||||
$(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
|
|
||||||
weibojs.requestAPI(cfg.api, function(data) {
|
|
||||||
$(el).find('.loading-wrap').remove();
|
|
||||||
const arr = data.tweets || [];
|
|
||||||
const limit = el.getAttribute('limit');
|
|
||||||
arr.forEach((item, i) => {
|
|
||||||
if (limit && i >= limit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var cell = '<div class="timenode" index="' + i + '">';
|
|
||||||
cell += '<div class="header">';
|
|
||||||
cell += '<div class="user-info">';
|
|
||||||
cell += '<img src="' + (data.user.avatar_hd || cfg.avatar) + '" onerror="javascript:this.src=\'' + cfg.avatar + '\';">';
|
|
||||||
cell += '<span>' + data.user.nick_name + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<span>' + item.created_at + '</span>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<div class="body">';
|
|
||||||
cell += '<a class="body" href="' + item.url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += item.content;
|
|
||||||
cell += '</a>';
|
|
||||||
// cell += '</div>';
|
|
||||||
// 每条微博的右下角 转发 评论 点赞
|
|
||||||
cell += '<div class="footer">';
|
|
||||||
cell += '<div class="flex left">';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<div class="flex right">';
|
|
||||||
cell += '<div class="item reaction repost">';
|
|
||||||
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<span>' + '🔗' + ' ' + item.reposts_count + '</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<span><svg t="1666270368054" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="200" height="200"><path d="M952 64H72C32.3 64 0 96.3 0 136v508c0 39.7 32.3 72 72 72h261l128 128c14 14 32.5 21.1 50.9 21.1s36.9-7 50.9-21.1l128-128h261c39.7 0 72-32.3 72-72V136c0.2-39.7-32.1-72-71.8-72zM222 462c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m290-7.7c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z m290 8c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z" p-id="2529"></path></svg> '
|
|
||||||
+ (item.comments_count || 0) + '</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
cell += '<div class="item reaction attitudes">';
|
|
||||||
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
|
||||||
cell += '<span>' + '👍' + ' ' + item.attitudes_count + '</span>';
|
|
||||||
cell += '</a>';
|
|
||||||
cell += '</div>';
|
|
||||||
|
|
||||||
cell += '</div>';
|
|
||||||
cell += '</div>';
|
|
||||||
// 右下角结束
|
|
||||||
$(el).append(cell);
|
|
||||||
});
|
|
||||||
}, function() {
|
|
||||||
$(el).find('.loading-wrap svg').remove();
|
|
||||||
$(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
|
|
||||||
$(el).find('.loading-wrap').addClass('error');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
$(function () {
|
|
||||||
const els = document.getElementsByClassName('stellar-weibo-api');
|
|
||||||
for (var i = 0; i < els.length; i++) {
|
|
||||||
const el = els[i];
|
|
||||||
const api = el.getAttribute('api'); // 这个API可以返回微博的json文件
|
|
||||||
if (api == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var cfg = new Object();
|
|
||||||
cfg.el = el;
|
|
||||||
cfg.api = api;
|
|
||||||
cfg.avatar = 'https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/avatar/round/3442075.svg';
|
|
||||||
weibojs.layoutDiv(cfg);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -136,3 +136,35 @@ var searchFunc = function(path, filter, wrapperId, searchId, contentId) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
utils.jq(() => {
|
||||||
|
var $inputArea = $("input#search-input");
|
||||||
|
if ($inputArea.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var $resultArea = document.querySelector("div#search-result");
|
||||||
|
$inputArea.focus(function() {
|
||||||
|
var path = ctx.search.path;
|
||||||
|
if (path.startsWith('/')) {
|
||||||
|
path = path.substring(1);
|
||||||
|
}
|
||||||
|
path = ctx.root + path;
|
||||||
|
const filter = $inputArea.attr('data-filter') || '';
|
||||||
|
searchFunc(path, filter, 'search-wrapper', 'search-input', 'search-result');
|
||||||
|
});
|
||||||
|
$inputArea.keydown(function(e) {
|
||||||
|
if (e.which == 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var observer = new MutationObserver(function(mutationsList, observer) {
|
||||||
|
if (mutationsList.length == 1) {
|
||||||
|
if (mutationsList[0].addedNodes.length) {
|
||||||
|
$('.search-wrapper').removeClass('noresult');
|
||||||
|
} else if (mutationsList[0].removedNodes.length) {
|
||||||
|
$('.search-wrapper').addClass('noresult');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe($resultArea, { childList: true });
|
||||||
|
});
|
|
@ -0,0 +1,36 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-fcircle-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const default_avatar = def.avatar;
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
const arr = data.article_data || [];
|
||||||
|
const limit = el.getAttribute('limit');
|
||||||
|
arr.forEach((item, i) => {
|
||||||
|
if (limit && i >= limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cell = '<div class="timenode" index="' + i + '">';
|
||||||
|
cell += '<div class="header">';
|
||||||
|
cell += '<div class="user-info">';
|
||||||
|
cell += '<img src="' + (item.avatar || default_avatar) + '" onerror="javascript:this.src=\'' + default_avatar + '\';">';
|
||||||
|
cell += '<span>' + item.author + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<span>' + item.created + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<a class="body" href="' + item.link + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += item.title;
|
||||||
|
cell += '</a>';
|
||||||
|
cell += '</div>';
|
||||||
|
$(el).append(cell);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,27 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-friends-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const default_avatar = def.avatar;
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
for (let item of (data.content || data)) {
|
||||||
|
var cell = `<div class="grid-cell user-card">`;
|
||||||
|
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.html_url || item.url}">`;;
|
||||||
|
cell += `<img src="${item.avatar_url || item.avatar || item.icon || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
||||||
|
cell += `<div class="name image-meta">`;
|
||||||
|
cell += `<span class="image-caption">${item.title || item.login}</span>`;
|
||||||
|
cell += `</div>`;
|
||||||
|
cell += `</a>`;
|
||||||
|
cell += `</div>`;
|
||||||
|
$(el).find('.grid-box').append(cell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,33 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-ghinfo-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// layout
|
||||||
|
utils.request(null, api, function(data) {
|
||||||
|
function fill(data) {
|
||||||
|
for (let key of Object.keys(data)) {
|
||||||
|
$(el).find("[type=text]#" + key).text(data[key]);
|
||||||
|
$(el).find("[type=link]#" + key).attr("href", data[key]);
|
||||||
|
$(el).find("[type=img]#" + key).attr("src", data[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const idx = el.getAttribute('index');
|
||||||
|
if (idx != undefined) {
|
||||||
|
const arr = data.content || data;
|
||||||
|
if (arr && arr.length > idx) {
|
||||||
|
let obj = arr[idx];
|
||||||
|
obj['latest-tag-name'] = obj['name'];
|
||||||
|
fill(arr[idx]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fill(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,10 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
const els = document.getElementsByClassName('stellar-marked-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const src = `${el.getAttribute('src')}?t=${new Date().getTime()}`;
|
||||||
|
utils.request(el, src, function(data) {
|
||||||
|
el.innerHTML = marked.parse(resp.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,73 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-memos-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const default_avatar = el.getAttribute('avatar') || def.avatar;
|
||||||
|
const limit = el.getAttribute('limit');
|
||||||
|
const host = api.replace(/https:\/\/(.*?)\/(.*)/i, '$1');
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
var users = [];
|
||||||
|
const filter = el.getAttribute('user');
|
||||||
|
if (filter && filter.length > 0) {
|
||||||
|
users = filter.split(",");
|
||||||
|
}
|
||||||
|
var hide = [];
|
||||||
|
const hideStr = el.getAttribute('hide');
|
||||||
|
if (hideStr && hideStr.length > 0) {
|
||||||
|
hide = hideStr.split(",");
|
||||||
|
}
|
||||||
|
data.forEach((item, i) => {
|
||||||
|
if (limit && i >= limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (item.user && item.user.login && users.length > 0) {
|
||||||
|
if (!users.includes(item.user.login)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let date = new Date(item.createdTs * 1000)
|
||||||
|
var cell = '<div class="timenode" index="' + i + '">';
|
||||||
|
cell += '<div class="header">';
|
||||||
|
if (!users.length && !hide.includes('user')) {
|
||||||
|
cell += '<div class="user-info">';
|
||||||
|
if (default_avatar.length > 0) {
|
||||||
|
cell += `<img src="${default_avatar}">`;
|
||||||
|
}
|
||||||
|
cell += '<span>' + item.creatorName + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
}
|
||||||
|
cell += '<span>' + date.toLocaleString() + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<div class="body">';
|
||||||
|
cell += marked.parse(item.content || '');
|
||||||
|
var imgs = [];
|
||||||
|
for (let res of item.resourceList) {
|
||||||
|
if (res.type?.includes('image/')) {
|
||||||
|
imgs.push(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (imgs.length > 0) {
|
||||||
|
cell += '<div class="tag-plugin image">';
|
||||||
|
for (let img of imgs) {
|
||||||
|
if (img.externalLink?.length > 0) {
|
||||||
|
cell += `<div class="image-bg"><img src="${img.externalLink}" data-fancybox="memos"></div>`;
|
||||||
|
} else {
|
||||||
|
cell += `<div class="image-bg"><img src="https://${host}/o/r/${img.id}" data-fancybox="memos"></div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cell += '</div>';
|
||||||
|
}
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '</div>';
|
||||||
|
$(el).append(cell);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
// 本插件由CardLink定制而成,原项目源码: https://github.com/Lete114/CardLink
|
||||||
|
function setCardLink(nodes) {
|
||||||
|
// If the `nodes` do not contain a `forEach` method, then the default `a[cardlink]` is used
|
||||||
|
nodes = 'forEach' in (nodes || {}) ? nodes : document.querySelectorAll('a[cardlink]')
|
||||||
|
nodes.forEach((el) => {
|
||||||
|
// If it is not a tag element then it is not processed
|
||||||
|
if (el.nodeType !== 1) return;
|
||||||
|
el.removeAttribute('cardlink');
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) return;
|
||||||
|
fetch(api).then(function(response) {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw new Error('Network response was not ok.');
|
||||||
|
}).then(function(data) {
|
||||||
|
var autofill = [];
|
||||||
|
const autofillStr = el.getAttribute('autofill');
|
||||||
|
if (autofillStr) {
|
||||||
|
autofill = autofillStr.split(',');
|
||||||
|
}
|
||||||
|
if (data.title && data.title.length > 0 && autofill.includes('title')) {
|
||||||
|
el.querySelector('.title').innerHTML = data.title;
|
||||||
|
el.title = data.title;
|
||||||
|
}
|
||||||
|
if (data.icon && data.icon.length > 0 && autofill.includes('icon')) {
|
||||||
|
el.querySelector('.img').style = 'background-image: url("' + data.icon + '");';
|
||||||
|
el.querySelector('.img').setAttribute('data-bg', data.icon);
|
||||||
|
}
|
||||||
|
let desc = el.querySelector('.desc');
|
||||||
|
if (desc && data.desc && data.desc.length > 0 && autofill.includes('desc')) {
|
||||||
|
desc.innerHTML = data.desc;
|
||||||
|
}
|
||||||
|
}).catch(function(error) {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-sites-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const default_avatar = def.avatar;
|
||||||
|
const default_cover = def.cover;
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
for (let item of data.content) {
|
||||||
|
var cell = `<div class="grid-cell site-card">`;
|
||||||
|
cell += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`;
|
||||||
|
cell += `<img src="${item.cover || item.screenshot}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_cover}\';"/>`;
|
||||||
|
cell += `<div class="info">`;
|
||||||
|
cell += `<img src="${item.icon || item.avatar || default_avatar}" onerror="javascript:this.removeAttribute(\'data-src\');this.src=\'${default_avatar}\';"/>`;
|
||||||
|
cell += `<span class="title">${item.title}</span>`;
|
||||||
|
cell += `<span class="desc">${item.description || item.url}</span>`;
|
||||||
|
cell += `</div>`;
|
||||||
|
cell += `</a>`;
|
||||||
|
cell += `</div>`;
|
||||||
|
$(el).find('.grid-box').append(cell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,108 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const reactions = {
|
||||||
|
'+1': '👍',
|
||||||
|
'-1': '👎',
|
||||||
|
'laugh': '😀',
|
||||||
|
'hooray': '🎉',
|
||||||
|
'confused': '😕',
|
||||||
|
'heart': '❤️',
|
||||||
|
'rocket': '🚀',
|
||||||
|
'eyes': '👀'
|
||||||
|
}
|
||||||
|
const timelines = document.getElementsByClassName('stellar-timeline-api');
|
||||||
|
for (var i = 0; i < timelines.length; i++) {
|
||||||
|
const el = timelines[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
const query = new URL(api).search;
|
||||||
|
const arr = data.content || data;
|
||||||
|
var users = [];
|
||||||
|
const filter = el.getAttribute('user');
|
||||||
|
if (filter && filter.length > 0) {
|
||||||
|
users = filter.split(",");
|
||||||
|
}
|
||||||
|
var hide = [];
|
||||||
|
const hideStr = el.getAttribute('hide');
|
||||||
|
if (hideStr && hideStr.length > 0) {
|
||||||
|
hide = hideStr.split(",");
|
||||||
|
}
|
||||||
|
console.log('arr', arr);
|
||||||
|
arr.forEach((item, i) => {
|
||||||
|
if (item.user && item.user.login && users.length > 0) {
|
||||||
|
if (!users.includes(item.user.login)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var cell = '<div class="timenode" index="' + i + '">';
|
||||||
|
cell += '<div class="header">';
|
||||||
|
if (!users.length && item.user && !hide.includes('user')) {
|
||||||
|
cell += '<a class="user-info" href="' + item.user.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<img src="' + item.user.avatar_url + '">';
|
||||||
|
cell += '<span>' + item.user.login + '</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
}
|
||||||
|
let date = new Date(item.created_at);
|
||||||
|
cell += '<span>' + date.toLocaleString() + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<div class="body">';
|
||||||
|
if (!hide.includes('title')) {
|
||||||
|
cell += '<p class="title">';
|
||||||
|
cell += '<a href="' + item.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += item.title || item.name || item.tag_name;
|
||||||
|
cell += '</a>';
|
||||||
|
cell += '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
cell += marked.parse(item.body || '');
|
||||||
|
if (!hide.includes('footer')) {
|
||||||
|
cell += '<div class="footer">';
|
||||||
|
cell += '<div class="flex left">';
|
||||||
|
if (item.labels) {
|
||||||
|
item.labels.forEach((label, i) => {
|
||||||
|
if (!query || !query.includes(encodeURI(label.name))) {
|
||||||
|
cell += '<div class="item label ' + label.name + '" style="background:#' + label.color + '18;border-color:#' + label.color + '36">';
|
||||||
|
cell += '<span>' + label.name + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (item.zipball_url) {
|
||||||
|
cell += '<a class="item download" href="' + item.zipball_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<span>📦 ' + item.tag_name + '.zip</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
}
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<div class="flex right">';
|
||||||
|
if (item.reactions?.total_count > 0) {
|
||||||
|
for (let key of Object.keys(reactions)) {
|
||||||
|
let num = item.reactions[key];
|
||||||
|
if (num > 0) {
|
||||||
|
cell += '<div class="item reaction ' + key + '">';
|
||||||
|
cell += '<span>' + reactions[key] + ' ' + item.reactions[key] + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.comments != null) {
|
||||||
|
cell += '<a class="item comments last" href="' + item.html_url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<span><svg t="1666270368054" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="200" height="200"><path d="M952 64H72C32.3 64 0 96.3 0 136v508c0 39.7 32.3 72 72 72h261l128 128c14 14 32.5 21.1 50.9 21.1s36.9-7 50.9-21.1l128-128h261c39.7 0 72-32.3 72-72V136c0.2-39.7-32.1-72-71.8-72zM222 462c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m290-7.7c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z m290 8c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z" p-id="2529"></path></svg> ' + (item.comments || 0) + '</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '</div>';
|
||||||
|
console.log('cell', cell, el);
|
||||||
|
$(el).append(cell);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,60 @@
|
||||||
|
utils.jq(() => {
|
||||||
|
$(function () {
|
||||||
|
const els = document.getElementsByClassName('stellar-weibo-api');
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
const el = els[i];
|
||||||
|
const api = el.getAttribute('api');
|
||||||
|
if (api == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const default_avatar = el.getAttribute('avatar') || def.avatar;
|
||||||
|
// layout
|
||||||
|
utils.request(el, api, function(data) {
|
||||||
|
const arr = data.tweets || [];
|
||||||
|
const limit = el.getAttribute('limit');
|
||||||
|
arr.forEach((item, i) => {
|
||||||
|
if (limit && i >= limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var cell = '<div class="timenode" index="' + i + '">';
|
||||||
|
cell += '<div class="header">';
|
||||||
|
cell += '<div class="user-info">';
|
||||||
|
cell += '<img src="' + (data.user.avatar_hd || default_avatar) + '" onerror="javascript:this.src=\'' + default_avatar + '\';">';
|
||||||
|
cell += '<span>' + data.user.nick_name + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<span>' + item.created_at + '</span>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<div class="body">';
|
||||||
|
cell += '<a class="body" href="' + item.url + '" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += item.content;
|
||||||
|
cell += '</a>';
|
||||||
|
// cell += '</div>';
|
||||||
|
// 每条微博的右下角 转发 评论 点赞
|
||||||
|
cell += '<div class="footer">';
|
||||||
|
cell += '<div class="flex left">';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<div class="flex right">';
|
||||||
|
cell += '<div class="item reaction repost">';
|
||||||
|
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<span>' + '🔗' + ' ' + item.reposts_count + '</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<span><svg t="1666270368054" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="200" height="200"><path d="M952 64H72C32.3 64 0 96.3 0 136v508c0 39.7 32.3 72 72 72h261l128 128c14 14 32.5 21.1 50.9 21.1s36.9-7 50.9-21.1l128-128h261c39.7 0 72-32.3 72-72V136c0.2-39.7-32.1-72-71.8-72zM222 462c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m290-7.7c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z m290 8c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z" p-id="2529"></path></svg> '
|
||||||
|
+ (item.comments_count || 0) + '</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
cell += '<div class="item reaction attitudes">';
|
||||||
|
cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
|
||||||
|
cell += '<span>' + '👍' + ' ' + item.attitudes_count + '</span>';
|
||||||
|
cell += '</a>';
|
||||||
|
cell += '</div>';
|
||||||
|
|
||||||
|
cell += '</div>';
|
||||||
|
cell += '</div>';
|
||||||
|
// 右下角结束
|
||||||
|
$(el).append(cell);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue