halo-theme-hao/templates/assets/js/halo.js
UPToZ 66417cb511 适配链接管理插件1.4.0版本
detailed:
1.适配链接管理插件1.4.0版本,解决前台索引查询链接报错问题。
2.当爱发电接口超时未返回内容时,显示默认数据。
2024-06-17 09:38:08 +08:00

486 lines
14 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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