import { DOMUtils, log, pops, utils } from "@/env"; import { ElementUtils } from "@/utils/ElementUtils"; import { getPageMaxZIndex } from "@components/env.base"; import { GestureBack } from "@components/utils/GestureBack"; import Qmsg from "qmsg"; import Viewer from "viewerjs"; import { unsafeWindow } from "ViteGM"; import smallWindowCSS from "./css/small-window.css?raw"; const MTSmallWindowIcon = { /** 锁图标 */ https: /*html*/ ` `, /** 开锁图标 */ http: /*html*/ ` `, /** 新标签页打开 */ openBlank: /*html*/ ` `, /** 关闭 */ close: /*html*/ ` `, /** 图片预览 */ image: /*html*/ ` `, /** 坐标的网站图标 */ mt: /*html*/ ` `, }; export const MTSmallWindow = { $key: { smallWindow: "smallWindow", }, $el: { $refreshIcon: null as any as HTMLElement, $webSiteIcon: null as any as HTMLElement, }, init() { let lockFn = new utils.LockFunction(() => { let forumlist = this.getForumList(); if (forumlist.length) { this.handleForumPost(forumlist); } }); let mutation = utils.mutationObserver(document.documentElement, { callback: (mutations, observer) => { lockFn.run(); }, config: { subtree: true, childList: true }, }); }, /** * 获取页面所有的帖子 */ getForumList() { return utils.getNodeListValue( ElementUtils.comiisForumList(), ElementUtils.comiisPostli(), ElementUtils.comiisMmlist() ); }, /** * 显示小窗 * @param title 标题 * @param url 链接 * @param imagesList 图片 */ showSmallWindow(title: string, url: string, imagesList: string[] = []) { let constructURL = new URL(url); let isHTTPS = constructURL.protocol.includes("https:"); let websiteTitle = /*html*/ `

${title}

${isHTTPS ? MTSmallWindowIcon.https : MTSmallWindowIcon.http}

${constructURL.host}

${ imagesList.length ? /*html*/ ` ${MTSmallWindowIcon.image} ` : "" } ${MTSmallWindowIcon.openBlank} ${MTSmallWindowIcon.close}
`; let $drawer = pops.drawer({ title: { enable: true, text: websiteTitle, html: true, style: "height: auto;line-height: normal;", }, content: { text: /*html*/ ` `, html: true, }, mask: { enable: true, clickEvent: { toClose: true, }, clickCallBack(originalRun, config) { getureBack.quitGestureBackMode(); }, }, btn: { ok: { enable: false, }, cancel: { enable: false, }, close: { enable: false, }, }, direction: "bottom", size: "92%", borderRadius: 18, style: smallWindowCSS, }); let $webSiteIcon = $drawer.$shadowRoot.querySelector(".small-window-website-icon")!; let $refreshIcon = $drawer.$shadowRoot.querySelector(".refresh-icon")!; let $imageIcon = $drawer.$shadowRoot.querySelector(".small-window-control-image-view")!; let $openBlankIcon = $drawer.$shadowRoot.querySelector(".small-window-control-open-blank")!; let $closeIcon = $drawer.$shadowRoot.querySelector(".small-window-control-close")!; let $titleText = $drawer.$shadowRoot.querySelector(".small-window-title-text")!; this.$el.$refreshIcon = $refreshIcon; this.$el.$webSiteIcon = $webSiteIcon; let $iframe = $drawer.$shadowRoot.querySelector("iframe")!; let $drag = $drawer.$shadowRoot.querySelector(".small-window-drag")!; let AnyTouch = pops.fn.Utils.AnyTouch(); let dragNode = new AnyTouch($drag); let smallWidowNode = $drawer.$pops; /* 小窗原始高度 */ let smallWidowNormalHeight = DOMUtils.height(smallWidowNode); dragNode.on("pan", (event) => { if (event.phase == "move" && event.displacementY > 0) { /* 当前为向下移动 */ smallWidowNode.style["transition"] = "none"; smallWidowNode.style["height"] = Math.abs(smallWidowNormalHeight - event.distanceY) + "px"; } if (event.isEnd) { /* 当前为停止移动,松开手指,判断在哪个区域,一半以上回归上面,一般以下,关闭 */ smallWidowNode.style["transition"] = "0.2s ease-in"; if (parseInt(smallWidowNode.style["height"]) > window.innerHeight / 2) { smallWidowNode.style["height"] = smallWidowNormalHeight + "px"; } else { // 关闭 $drawer.close(); } } }); let getureBack = new GestureBack({ hash: this.$key.smallWindow, useUrl: true, win: unsafeWindow, beforeHistoryBackCallBack: (isUrlChange) => { $drawer.close(); }, }); getureBack.enterGestureBackMode(); DOMUtils.on($titleText, "click", (event) => { DOMUtils.preventEvent(event); utils.copy(`『${title}』 - ${url}`); Qmsg.success("已复制链接"); }); DOMUtils.on($imageIcon, "click", (event) => { DOMUtils.preventEvent(event); log.info(`查看图片`, imagesList); var viewerULNodeHTML = ""; imagesList.forEach((item) => { viewerULNodeHTML += `
  • `; }); var viewerULNode = DOMUtils.toElement(`
      ${viewerULNodeHTML}
    `, false, false); let viewer = new Viewer(viewerULNode, { inline: false, url: "data-src", zIndex: (() => { return getPageMaxZIndex(); })(), hidden: () => { viewer.destroy(); }, }); viewer.zoomTo(1); viewer.show(); }); DOMUtils.on($closeIcon, "click", (event) => { DOMUtils.preventEvent(event); getureBack.quitGestureBackMode(); }); DOMUtils.on($openBlankIcon, "click", (event) => { DOMUtils.preventEvent(event); window.open(url, "_blank"); }); DOMUtils.on($webSiteIcon, "click", (event) => { DOMUtils.preventEvent(event); $iframe.contentWindow!.location.reload(); this.checkIframeReadyState($iframe); }); this.checkIframeReadyState($iframe); }, /** * 对帖子进行处理,实现点击某个区域打开小窗 * @param forumlist */ async handleForumPost(forumlist: HTMLElement[]) { forumlist.forEach(($forum) => { if ($forum.getAttribute("data-injection-small-window")) { return; } /* 帖子标题 */ let title = DOMUtils.text($forum.querySelector(".mmlist_li_box h2 a")!); // 防止获取的标题是空的 if (title == "" || title == null) { title = DOMUtils.text($forum.querySelector(".mmlist_li_box a")!); } title = title.trim(); /* 帖子地址 */ let url = $forum.querySelector(".mmlist_li_box a")!.href; /* 帖子内图片列表 */ var imagesList: string[] = []; $forum.setAttribute("data-injection-small-window", "true"); $forum.setAttribute("data-injection-small-window-url", url); $forum.setAttribute("data-injection-small-window-title", title); $forum.querySelectorAll(".comiis_pyqlist_img img").forEach(($img) => { imagesList.push($img.getAttribute("src")!); }); $forum.querySelectorAll(".comiis_pyqlist_imgs img").forEach(($img) => { imagesList.push($img.getAttribute("src")!); }); $forum.querySelectorAll(".mmlist_li_box a").forEach(($anchor) => { $anchor.removeAttribute("href"); $anchor.setAttribute("data-href", url); }); let $mmlist_li_box = $forum.querySelector(".mmlist_li_box"); DOMUtils.on($mmlist_li_box, "click", function (event) { /* 鼠标相对屏幕横坐标 */ var mouseClickPosX = Number(event.clientX); if (document.body.offsetWidth / 2 > mouseClickPosX) { window.location.href = url; } else { MTSmallWindow.showSmallWindow(title, url, imagesList); } }); }); }, /** * 检测 iframe是否加载完毕 * @param iframe */ checkIframeReadyState(iframe: HTMLIFrameElement) { this.showRefreshIcon(); let intervalId = setInterval(() => { if (iframe.contentWindow) { clearInterval(intervalId); let iframeDOMUtils = DOMUtils.createDOMUtils({ document: iframe.contentWindow!.document, // @ts-ignore window: iframe.contentWindow!, globalThis: iframe.contentWindow!, // @ts-ignore self: iframe.contentWindow!, top: top!, }); iframeDOMUtils.onReady(() => { log.success("小窗内容已加载完毕"); this.hideRefreshIcon(); }); } }, 400); }, hideRefreshIcon() { this.$el.$refreshIcon.style.display = "none"; this.$el.$webSiteIcon.style.display = ""; }, showRefreshIcon() { this.$el.$refreshIcon.style.display = ""; this.$el.$webSiteIcon.style.display = "none"; }, };