// ==UserScript== // @name 游戏社区(TapTap)列表页贴子预览 // @namespace https://github.com/QIUZAIYOU/Taptap-PostPreview // @license GPL-3.0 License // @version 1.3.0 // @description TapTap游戏社区列表页贴子(除图片和视频贴)卡片新增预览按钮,可在列表页直接预览贴子内容。 // @author QIAN // @match *://www.taptap.cn/app/*/topic* // @grant GM_addStyle // @require https://scriptcat.org/lib/513/2.0.0/ElementGetter.js#sha256=KbLWud5OMbbXZHRoU/GLVgvIgeosObRYkDEbE/YanRU= // @supportURL https://github.com/QIUZAIYOU/Taptap-PostPreview // @homepageURL https://github.com/QIUZAIYOU/Taptap-PostPreview // @icon https://assets.tapimg.com/cupid-apps/web-app/favicon.2.ico // @downloadURL none // ==/UserScript== (function () { 'use strict'; const selecter = { tap: '#tap', momentCardFooter: '.moment-card__footer', previewWrapper: '#previewWrapper', previewIframe: '#previewIframe', previewIframeMask: '#previewIframeMask', previewContentHeader: 'header', previewContentMain: 'main' } const styles = { PreviewWrapperStyle: '#previewWrapper{position:fixed;top:50%;left:50%;overflow:hidden;box-sizing:border-box;width:600px;height:97vh;border:2px solid #00d9c5;border-radius:10px;background:#191919;transform:translate(-50%,-50%)}#previewWrapper::backdrop{backdrop-filter:blur(3px)}#previewIframe{width:100%;height:100%;border:none;background:#191919}#previewIframeMask{position:absolute;display:flex;background:#191919;inset:0;align-items:center;justify-content:center}', PreviewIframeStyle: 'body{background:#191919!important}header{display:none!important}main{margin-left:0!important}' } const utils = { /** * 休眠 * @param {Number} 时长 * @returns */ sleep(times) { return new Promise(resolve => setTimeout(resolve, times)) }, /** * 创建并插入元素至目标元素 * @param {String} Html 字符串 * @param {Element} 目标元素 * @param {String} 插入方法(before/after/prepend/append) * @returns 被创建的元素 */ createElementAndInsert(HtmlString, target, method) { const element = elmGetter.create(HtmlString, target) target[method](element) return element }, /** * 向文档插入自定义样式 * @param {String} id 样式表id * @param {String} css 样式内容 */ insertStyleToDocument(id, css) { const styleElement = GM_addStyle(css) styleElement.id = id }, htmlStringToDom(htmlString) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = htmlString.trim(); return tempDiv.firstChild; } } const modules = { insertPreviewElementToDocument() { const previewElementHtml = `
` const previewWrapper = document.getElementById('previewWrapper') if (previewWrapper) return previewWrapper return utils.createElementAndInsert(previewElementHtml, document.body, 'append') }, async insertPreviewButtonToMomentCard() { const previewButtonHtml = ` ` const [$previewWrapper, $previewIframe, $previewIframeMask] = await elmGetter.get([selecter.previewWrapper, selecter.previewIframe, selecter.previewIframeMask]) const previewIframeWindow = $previewIframe.contentWindow $previewWrapper.addEventListener('toggle', (event) => { if (event.newState === 'closed') { $previewIframe.src = '' $previewIframeMask.style.display = 'flex' document.querySelector(selecter.tap).style.pointerEvents = 'auto' } }) $previewIframe.addEventListener('load', async () => { const [$previewContentHeader, $previewContentMain] = await elmGetter.get([selecter.previewContentHeader, selecter.previewContentMain], previewIframeWindow.document) if ($previewContentHeader && $previewContentMain) { $previewContentHeader.style.display = 'none' $previewContentMain.style.marginLeft = '0' $previewIframeMask.style.display = 'none' } }) elmGetter.each(selecter.momentCardFooter, (momentCardFooter) => { const previewButton = utils.createElementAndInsert(previewButtonHtml, momentCardFooter, 'append') previewButton.addEventListener('click', (event) => { event.preventDefault() event.stopPropagation() $previewWrapper.showPopover() $previewIframe.src = momentCardFooter.parentElement.querySelector('a[href*="moment"]').href document.querySelector(selecter.tap).style.pointerEvents = 'none' }) }) } } utils.insertStyleToDocument('PreviewWrapperStyle', styles.PreviewWrapperStyle) modules.insertPreviewElementToDocument() modules.insertPreviewButtonToMomentCard() })();