halo-theme-hao/templates/assets/js/halo.js
2024-04-12 14:35:37 +08:00

463 lines
13 KiB
JavaScript
Raw 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 user_id = GLOBAL_CONFIG.source.power.userId
var show_num = GLOBAL_CONFIG.source.power.showNum
function getPower() {
const url = GLOBAL_CONFIG.source.power.url + user_id
fetch(url)
.then(res => res.json())
.then(data => {
if (200 === data["ec"]) {
var values = data["data"]["list"]
saveToLocal.set('power-data', JSON.stringify(values), 10 / (60 * 24))
renderer(values);
}
})
}
function renderer(values) {
var data = getArrayItems(values, 1);
let powerStar = document.getElementById("power-star")
if (values.length === 0) {
powerStar.href = GLOBAL_CONFIG.source.power.powerLink
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url('/themes/theme-hao/assets/images/afadian/afadian.webp')">
</div>
<div class="power-star-body">
<div id="power-star-title">还没有人赞助~</div>
<div id="power-star-desc">为爱发电,点击赞助</div>
</div>`;
} else {
if (powerStar) {
powerStar.href = "https://afdian.net/u/" + data[0].user_id
powerStar.innerHTML = `
<div id="power-star-image" style="background-image: url(${data[0].avatar})">
</div>
<div class="power-star-body">
<div id="power-star-title">${data[0].name}</div>
<div id="power-star-desc">更多支持,为爱发电</div>
</div>`;
}
if (values.length > 1) {
var i = 0;
var htmlText = '';
for (let value of values) {
if (i > parseInt(show_num)) {
break;
}
htmlText +=
` <a href="${"https://afdian.net/u/" + value["user_id"]}" rel="external nofollow" target="_blank" th:title="${value["name"]}">${value["name"]}</a>`;
i = i + 1;
}
if (document.getElementById("power-item-link")) {
document.getElementById("power-item-link").innerHTML = htmlText;
}
}
}
}
function init() {
const data = saveToLocal.get('power-data')
if (data) {
renderer(JSON.parse(data))
} else {
getPower()
}
}
document.getElementById("power-star") && init()
},
checkAd() {
var default_enable = GLOBAL_CONFIG.source.footer.default_enable
if (default_enable) {
var adElement = document.getElementById("footer-banner");
var notMusic = document.body.getAttribute("data-type") != "music"; // 检测是否为音乐页面
if ((adElement.offsetWidth <= 0 || adElement.offsetHeight <= 0) && notMusic) {
// 元素不可见,可能被拦截
console.log("Element may be blocked by AdBlocker Ultimate");
alert("页脚信息可能被AdBlocker Ultimate拦截请检查广告拦截插件")
}
}
}
}