import { Panel } from "@components/setting/panel"; import beautifyMarkdownCSS from "./css/beautifyMarkdown.css?raw"; import beautifyButtonCSS from "./css/beautifyButton.css?raw"; import beautifyRadioCSS from "./css/beautifyRadio.css?raw"; import beautifyInputCSS from "./css/beautifyInput.css?raw"; import beautifyTextAreaCSS from "./css/beautifyTextArea.css?raw"; import beautifyUploadImageCSS from "./css/beautifyUploadImage.css?raw"; import compatibleBeautifyCSS from "./css/compatibleBeautify.css?raw"; import beautifyTopNavigationBarCSS from "./css/beautifyTopNavigationBar.css?raw"; import beautifyHomeCSS from "./css/beautifyHome.css?raw"; import beautifyFeedbackCSS from "./css/beautifyFeedback.css?raw"; import { $, $$, addStyle, DOMUtils, log, utils } from "@/env"; import i18next from "i18next"; import { CommonUtil } from "@components/utils/CommonUtil"; import { GreasyforkRouter } from "@/router/GreasyforkRouter"; export const GreasyforkBeautify = { init() { Panel.execMenuOnce("beautifyPage", () => { return this.beautifyPageElement(); }); Panel.execMenuOnce("beautifyGreasyforkBeautify", () => { return this.beautifyGreasyforkBeautify(); }); Panel.execMenuOnce("beautifyUploadImage", () => { return this.beautifyUploadImage(); }); Panel.execMenuOnce("beautifyTopNavigationBar", () => { return this.beautifyTopNavigationBar(); }); }, /** * 美化页面元素,包括Markdown */ beautifyPageElement() { log.info("美化页面元素"); const result = []; result.push(addStyle(beautifyMarkdownCSS)); result.push(addStyle(beautifyButtonCSS)); result.push(addStyle(beautifyRadioCSS)); result.push(addStyle(beautifyInputCSS)); result.push(addStyle(beautifyTextAreaCSS)); result.push( addStyle(/*css*/ ` p:has(input[type="submit"][name="update-and-sync"]){ margin-top: 10px; } `) ); DOMUtils.onReady(() => { let $markupChoice = $('a[target="markup_choice"][href*="daringfireball.net"]'); if ($markupChoice) { $markupChoice.parentElement!.replaceChild( DOMUtils.createElement("span", { textContent: "Markdown", }), $markupChoice ); } // markdown 解析任务列表并转换 // [x] // [] $$(".user-content ul li").forEach(($li) => { let $first = $li.firstChild; if ($first?.nodeName === "#text") { if ($first.textContent?.startsWith("[x] ")) { $first.textContent = $first.textContent!.replace("[x] ", ""); DOMUtils.prepend( $li, /*html*/ ` ` ); } else if ($first.textContent?.startsWith("[ ] ")) { $first.textContent = $first.textContent!.replace("[ ] ", ""); DOMUtils.prepend( $li, /*html*/ ` ` ); } } }); // github风格的警告列表 // > [!NOTE] // > 有用的信息,用户在浏览内容时应该知道。 // > [!TIP] // > 提供更好或更容易做事的有益建议。 // > [!IMPORTANT] // > 用户为了实现目标所需的关键信息。 // > [!WARNING] // > 紧急信息,需要用户立即注意以避免问题。 // > [!CAUTION] // > 关于某些操作的风险或负面结果的建议。 let warningListMap = { "[!NOTE]": /*html*/ `

Note

`, "[!TIP]": /*html*/ `

Tip

`, "[!IMPORTANT]": /*html*/ `

Important

`, "[!WARNING]": /*html*/ `

Warning

`, "[!CAUTION]": /*html*/ `

Caution

`, }; let warningList = Object.keys(warningListMap); $$(".user-content blockquote").forEach(($blockQuote) => { Array.from($blockQuote.children).forEach(($child) => { let htmlStr = DOMUtils.html($child as HTMLElement); if ($child.nodeName === "P") { let findValue = warningList.find((value) => { return htmlStr.toLowerCase().startsWith(value.toLowerCase()); }); if (findValue) { DOMUtils.html($child as HTMLElement, htmlStr.replace(findValue, "")); DOMUtils.before($child as HTMLElement, warningListMap[findValue as keyof typeof warningListMap]); if (DOMUtils.html($child as HTMLElement) === "") { $child.remove(); } } } }); }); // 把警告列表的样式进行迁移合并 $$(".user-content > blockquote").forEach(($blockQuote) => { Array.from($blockQuote.querySelectorAll(".markdown-alert-title")).forEach( ($markdownAlertTitle) => { let $markdownAlert = DOMUtils.createElement( "div", { className: "markdown-alert markdown-alert-tip", }, { "data-type": $markdownAlertTitle.getAttribute("data-type")!, } ); while ($markdownAlertTitle.nextSibling) { if (($markdownAlertTitle.nextSibling as HTMLElement)?.classList?.contains("markdown-alert-title")) { break; } DOMUtils.append($markdownAlert, $markdownAlertTitle.nextSibling as HTMLElement); } DOMUtils.prepend($markdownAlert, $markdownAlertTitle); DOMUtils.before($blockQuote, $markdownAlert); } ); }); if (GreasyforkRouter.isHome()) { result.push(addStyle(beautifyHomeCSS)); } else if (GreasyforkRouter.isScriptsFeedback()) { result.push(addStyle(beautifyFeedbackCSS)); let $noRating = $('.radio-label[for*="discussion_rating_0"]'); if ($noRating) { $noRating.innerHTML = $noRating.innerHTML.replace( "不评分", '不评分' ); } let $badRating = $('.radio-label[for*="discussion_rating_2"]'); if ($badRating) { $badRating.innerHTML = $badRating.innerHTML.replace( "差评", '差评' ); } let $okRating = $('.radio-label[for*="discussion_rating_3"]'); if ($okRating) { $okRating.innerHTML = $okRating.innerHTML.replace( "一般", '一般' ); } let $goodRating = $('.radio-label[for*="discussion_rating_4"]'); if ($goodRating) { $goodRating.innerHTML = $goodRating.innerHTML.replace( "好评", '好评' ); } } else if (GreasyforkRouter.isScriptAdmin()) { if (!$('input[type="submit"][name="update-only"]')) { result.push( addStyle(/*css*/ ` .indented{ padding-left: unset; } `) ); } } }); return result; }, /** * 美化 Greasyfork Beautify脚本 */ beautifyGreasyforkBeautify() { log.info("美化 Greasyfork Beautify脚本"); const result = []; result.push(addStyle(compatibleBeautifyCSS)); if (utils.isPhone()) { /* 移动端 */ result.push( addStyle(/*css*/ ` section#script-info, section.text-content, div.width-constraint table.text-content.log-table{ margin-top: 80px; } div.width-constraint div.sidebarred{ padding-top: 80px; } div.width-constraint div.sidebarred .sidebar{ top: 80px; }`) ); } else { result.push( addStyle(/*css*/ ` section#script-info{ margin-top: 10px; }`) ); } return result; }, /** * 美化上传图片 */ beautifyUploadImage() { log.info("美化上传图片"); const result = []; result.push(addStyle(beautifyUploadImageCSS)); DOMUtils.onReady(() => { /** * 清空错误的提示 * @param element */ function clearErrorTip(element: HTMLElement) { while (element.nextElementSibling) { element.parentElement!.removeChild(element.nextElementSibling); } } const $fileInputList = $$('input[type="file"]'); $fileInputList.forEach(($input) => { if ($input.getAttribute("name") === "code_upload") { return; } if ($input.hasAttribute("accept") && $input.getAttribute("accept")!.includes("javascript")) { return; } DOMUtils.on($input, ["propertychange", "input"], function (event) { clearErrorTip(event.target as HTMLInputElement); const chooseImageFiles = (event.currentTarget as HTMLInputElement).files; if (!chooseImageFiles) { return; } if (chooseImageFiles.length === 0) { return; } log.info("选择的图片", chooseImageFiles); if (chooseImageFiles.length > 5) { DOMUtils.after( $input, DOMUtils.createElement("p", { textContent: i18next.t(`❌ 最多同时长传5张图片`), }) ); } const notAllowImage: File[] = []; Array.from(chooseImageFiles).forEach((imageFile) => { if (imageFile.size > 204800 || !imageFile.type.match(/png|jpg|jpeg|gif|apng|webp/i)) { notAllowImage.push(imageFile); } }); if (notAllowImage.length === 0) { return; } notAllowImage.forEach((imageFile) => { DOMUtils.after( $input, DOMUtils.createElement("p", { textContent: i18next.t("❌ 图片:{{name}} 大小:{{size}}", { name: imageFile.name, size: imageFile.size, }), }) ); }); }); }); const $textAreaSelectorString = [ /* 某条反馈内的回复框 */ "textarea#comment_text", /* 反馈页面的回复框 */ "textarea.comment-entry", ]; $textAreaSelectorString.forEach((selector) => { DOMUtils.on(selector, "paste", (event) => { log.info("触发粘贴事件", event); setTimeout(() => { /* 主动触发input */ DOMUtils.emit($fileInputList, "input"); }, 100); }); }); }); return result; }, /** * 美化顶部导航栏 */ beautifyTopNavigationBar() { log.info("美化顶部导航栏"); const result: (HTMLStyleElement | undefined)[] = []; result.push(addStyle(beautifyTopNavigationBarCSS)); if (window.outerWidth > 550) { result.push(CommonUtil.addBlockCSS(".with-submenu")); DOMUtils.onReady(() => { const $siteNav = $("#site-nav")!; const $siteNavNav = $siteNav.querySelector("nav")!; // 把更多的内容添加到顶部导航栏中 $$(".with-submenu nav li").forEach(($ele) => { $siteNavNav.appendChild($ele); }); }); } return result; }, };