// ==UserScript==
// @name 添加自定义css和js(广告屏蔽等)
// @description 可自定义css选择器屏蔽页面广告,添加js脚本
// @namespace _cus_ad_sp
// @version 2.3.17
// @author vizo
// updateUrl http://dwz.win/ac4h
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/tiny-oss.min.js
// @require https://cdn.jsdelivr.net/npm/vio-utils/index.min.js
// @require https://cdn.jsdelivr.net/npm/@vizoy/[email protected]/index.min.js
// @include /https?\:\/\/(?!greasyfork).*/
// @run-at document-start
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_registerMenuCommand
// @noframes
// ==/UserScript==
'use strict'
;(function() {
if (vio.isMobile()) return
let k = GM_getValue(`_cfg_${location.host}`) || {}
k = typeof k === 'string' ? JSON.parse(k) : k
if (k.css && !k.disCSS) {
GM_addStyle(`sty9z1p52{}\n${k.css}\n`)
}
})();
GM_addStyle(`
.GM_dn85b {
display: none !important;
}
.GM_vh85b {
visibility: hidden !important;
}
.GM-yisi-Asd::before,
.GM-certain-Asd::before {
content: '疑似广告';
width: 100%;
height: 100%;
font-size: 16px;
color: #ddd;
display: flex;
justify-content: center;
align-items: center;
font-weight: normal;
font-style: normal;
font-family: Arial sans-serif;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.GM-certain-Asd::before {
content: '已屏蔽广告';
}
.GM-yisi-Asd > *,
.GM-certain-Asd > * {
visibility: hidden !important;
opacity: 0 !important;
}
.GM-yisi-Asd:hover > *,
.GM-certain-Asd:hover > * {
visibility: visible !important;
opacity: 0.8 !important;
animation: anim5z 1.4s both;
}
@keyframes anim5z {
0% {
opacity: 0;
}
30% {
opacity: 0;
}
100% {
opacity: 0.8;
}
}
@keyframes anim8z {
80% {
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
.GM-yisi-Asd:hover::before,
.GM-certain-Asd:hover::before {
animation: anim8z 1.2s both;
}
#wp5sn [hidden] {
display: none !important;
}
#wp5sn, #wp5sn * {
margin: 0;
padding: 0;
box-sizing: border-box !important;
}
#wp5sn {
width: 28vw;
height: 68vh;
min-width: 400px;
padding: 30px;
background: #fff;
border-radius: 3px;
font-family: sans-serif,"HelveticaNeue",Helvetica,"PingFangSC","MicrosoftYaHei","HiraginoSansGB",Arial;
line-height: 1.5;
font-size: 12px;
resize: both;
box-shadow: 0 0 5px #ccc;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 50050;
margin: auto;
}
#wp5sn .mwp_5c {
height: 100%;
display: flex;
flex-direction: column;
}
#wp5sn .tit1v {
color: #555;
font-size: 18px;
text-align: center;
margin-bottom: 15px;
}
#wp5sn .c7d-item {
margin-bottom: 10px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
#wp5sn .allset-item {
flex: 1;
}
#wp5sn .css-item-xh {
flex: 3;
transition: flex .3s;
}
#wp5sn .js-item-xh {
flex: 1;
transition: flex .3s;
}
#wp5sn .mwp_5c.expandJS .css-item-xh {
flex: 1;
}
#wp5sn .mwp_5c.expandJS .js-item-xh {
flex: 3;
}
#wp5sn .stiz {
font-size: 14px;
color: #555;
margin-bottom: 3px;
position: relative;
text-align: left;
display: flex;
}
#wp5sn .tamp-cfg-modal {
width: 250px;
height: 170px;
padding: 10px;
border-radius: 2px;
background: #f1f1f1;
position: absolute;
top: -50px;
right: 0;
bottom: 0;
left: 0;
margin: auto;
z-index: 2;
}
#wp5sn .tamp-cfg-modal .txa-cfg {
width: 100%;
height: 100%;
resize: none;
color: #777 !important;
font-family: Consolas;
font-size: 12px;
padding: 6px;
overflow-y: auto;
border: 1px solid #e6e6e6;
background: #fafafa;
}
#wp5sn .tamp-cfg-modal .txa-cfg::-webkit-input-placeholder {
color: #ccc !important;
}
#wp5sn .stiz .s0l {
flex: 1;
}
#wp5sn .stiz .s0r {
color: #09e;
cursor: pointer;
user-select: none;
margin-left: 10px;
}
#wp5sn .stiz .s0r.on {
color: #9a9a9a;
}
#wp5sn .oss-zbtn {
color: #c7c7c7;
cursor: pointer;
user-select: none;
margin-right: 10px;
}
#wp5sn .view-all-set {
color: #09e;
cursor: pointer;
user-select: none;
}
#wp5sn .st1k {
display: flex;
}
#wp5sn .st1k .s1p {
flex: 1;
}
#wp5sn .st1k .s2p {
width: 65px;
color: #09e;
cursor: pointer;
text-align: right;
white-space: nowrap;
overflow: hidden;
}
#wp5sn .inpy {
flex: 0 0 auto;
height: 32px;
border: 1px solid #ddd;
color: #555;
background: #fff;
border-radius: 2px;
padding: 0 10px;
outline: none;
}
#wp5sn .inpy:focus {
border: 1px solid #c1c1c1;
}
#wp5sn .txtr1z {
width: 100%;
flex: 1;
color: #555;
padding: 6px;
line-height: 1.4;
overflow-x: hidden;
overflow-y: auto;
border-radius: 2px;
border: 1px solid #ddd;
background: #fff;
font-size: 12px;
resize: none;
white-space: pre-line;
outline: none;
font-family: Consolas,sans-serif,"Helvetica Neue",Helvetica,"PingFang SC","Microsoft YaHei";
}
#wp5sn .txtr1z::-webkit-input-placeholder {
color: #c5c5c5;
}
#wp5sn .txtr1z:focus {
border: 1px solid #39e;
}
#wp5sn .txtr1z.disabled {
color: #999;
background: #f5f5f5;
}
#wp5sn .txtr1z::-webkit-scrollbar {
width: 4px;
}
#wp5sn .txtr1z::-webkit-scrollbar-corner,
#wp5sn .txtr1z::-webkit-scrollbar-track {
background-color: #fff;
}
#wp5sn .txtr1z::-webkit-scrollbar-thumb {
background: #fff;
}
#wp5sn .txtr1z:hover::-webkit-scrollbar-thumb {
background: #e1e1e1;
}
#wp5sn .txtr1z:hover::-webkit-scrollbar-corner,
#wp5sn .txtr1z:hover::-webkit-scrollbar-track {
background-color: #f7f7f7;
}
#wp5sn .btn-w {
margin-top: 5px;
display: flex;
flex-direction: row-reverse;
}
#wp5sn .btn-w .c5kbtn {
width: 90px;
height: 32px;
border-radius: 2px;
margin-right: 10px;
font-family: sans-serif,"Helvetica Neue",Helvetica,"PingFang SC","Microsoft YaHei" !important;
cursor: pointer;
outline: none;
border: 0;
}
#wp5sn .btn-w .c5kbtn.b1 {
color: #fff !important;
background: #09e !important;
}
#wp5sn .btn-w .c5kbtn.b2 {
color: #555 !important;
background: #f1f1f1 !important;
}
#wp5sn .btn-w .c5kbtn:first-child {
margin-right: 0;
}
#wp5sn .btn-w .c5kbtn:focus {
border: 0;
}
#wp5sn .btn-w .c5kbtn:hover {
opacity: 0.9;
}
`)
const G = {
ifrIgnore: ['weixin.qq.com', 'captcha.qq.com', 'geetest.com', 'login.taobao.com', 'aliyundrive.com', 'mail.163.com'],
hostIgnore: ['taobao.com', 'jd.com', 'tmall.com', 'localhost', '192.168', 'npmjs.com', 'jsdelivr.com', 'github.com', 'fastgit.org'],
linkIgnore: ['github.com'],
html: `
<div id="wp5sn" v-show="dialog1s">
<div class="mwp_5c" :class="{'expandJS': isExpandJS}">
<div class="tit1v">设置</div>
<div class="tamp-cfg-modal" v-show="isShowTampModal">
<textarea class="txa-cfg" @change="changeTampCfg" v-model="tampCfgVal" placeholder="oss配置"></textarea>
</div>
<div class="c7d-item">
<p class="stiz">
<span class="s0l">打开面板快捷键</span>
<span class="oss-zbtn" @click="hdlTgOssModal">oss</span>
<span class="view-all-set" @click="hdlViewAllSet">{{ viewSetText }}</span>
</p>
<input type="text" class="inpy" v-model="eKey" placeholder="请输入a-z的任意字母">
</div>
<div class="c7d-item css-item-xh" v-show="!showAllSet">
<p class="stiz">
<span class="s0l">添加css(不含style标签)</span>
<span class="s0r" :class="{on: disCSS}" @click="hdlTgDisCss">{{ disCssText }}</span>
</p>
<textarea class="txtr1z" :class="{'disabled': disCSS}" v-model="texCssVal" :readonly="disCSS" spellcheck="false" placeholder="请输入css代码" @click="hdlExpandJSJs(1)"></textarea>
</div>
<div class="c7d-item js-item-xh" v-show="!showAllSet">
<p class="stiz">
<span class="s0l">添加js(不含script标签)</span>
<span class="s0r" :class="{on: disJS}" @click="hdlTgDisJs">{{ disJsText }}</span>
</p>
<textarea class="txtr1z" :class="{'disabled': disJS}" v-model="texJsVal" :readonly="disJS" spellcheck="false" placeholder="请输入js代码" @click="hdlExpandJSJs(2)"></textarea>
</div>
<div class="c7d-item allset-item" v-show="showAllSet">
<p class="stiz st1k">
<span class="s1p">已添加的网站(可删除) {{ addedNum }} 个 </span>
<span class="s2p imt-c" @click="hdlImportCfg">导入配置</span>
<span class="s2p ext-c" @click="hdlExportCfg">导出配置</span>
</p>
<input type="file" hidden ref="inp_hide" @change="hdlUpFile">
<textarea class="txtr1z" v-model="allAddedStr"></textarea>
</div>
<div class="btn-w">
<button class="c5kbtn b2" @click="hdlCancel">取消</button>
<button class="c5kbtn b1" @click="hdlSave">保存</button>
</div>
</div>
</div>
`,
}
const vm = new Vue({
data() {
return {
// 模态框状态
dialog1s: false,
// 快捷键名称
eKey: '',
showAllSet: false,
// css代码
texCssVal: '',
// js代码
texJsVal: '',
// 已添加的网站
allAddedStr: '',
disCSS: false,
disJS: false,
// 是否展开js
isExpandJS: false,
// oss配置modal
isShowTampModal: false,
tampCfgVal: '',
}
},
computed: {
viewSetText() {
return this.showAllSet ? '查看当前网站' : '查看全部网站'
},
addedNum() {
return this.allAddedStr
.split('\n')
.filter(v => !!v)
.length
},
disCssText() {
return this.disCSS ? '已禁用' : '禁用css'
},
disJsText() {
return this.disJS ? '已禁用' : '禁用js'
},
},
watch: {
eKey(nVal) {
this.eKey = /[a-z]/.test(nVal) ? nVal.slice(0, 1) : ''
GM_setValue('_gus_keyboard', this.eKey)
},
dialog1s(nVal) {
if (!nVal) {
this.showAllSet = false
this.isShowTampModal = false
}
},
},
methods: {
setGmVal(val) {
return GM_setValue(`_cfg_${location.host}`, val)
},
getGmVal() {
let gmVal = GM_getValue(`_cfg_${location.host}`) || {}
return typeof gmVal === 'string' ? JSON.parse(gmVal) : gmVal
},
hdlTgOssModal() {
this.isShowTampModal = !this.isShowTampModal
},
hdlExpandJSJs(type) {
this.isExpandJS = type === 2
},
changeTampCfg() {
GM_setValue('tampOssCfg7n', this.tampCfgVal)
},
async hdlSave() {
if (!this.showAllSet) {
this.saveCssAndJs()
this.initAddedWebToTextArea()
} else {
this.updateTextAreaValToGm()
await this.saveJsonToOss('state')
await this.saveJsonToOss('cfg')
location.reload()
}
this.dialog1s = false
},
hdlCancel() {
this.dialog1s = false
},
// 禁用css
hdlTgDisCss() {
this.disCSS = !this.disCSS
},
// 禁用js
hdlTgDisJs() {
this.disJS = !this.disJS
},
async saveCssAndJs() {
let css = `<style class="sty9z1p52">${this.texCssVal}</style>`
document.head.insertAdjacentHTML('beforeend', css)
Array.from(document.querySelectorAll('.sty9z1p52')).forEach((v, i, y) => {
if (i !== y.length - 1) {
v.remove()
} else {
v.disabled = this.disCSS
}
})
const gm = this.getGmVal()
this.setGmVal({
...gm,
css: this.texCssVal,
js: this.texJsVal,
disCSS: this.disCSS,
disJS: this.disJS,
})
// 同步至oss
if ( !await this.saveJsonToOss('state') ) {
alert('同步失败, 请导出配置后在其他网站重新上传配置就能同步了')
return
}
await this.saveJsonToOss('cfg')
if (gm.disJS !== this.disJS || gm.js !== this.texJsVal) {
await vio.timeout(500)
location.reload()
}
},
saveJsonToOss(name) {
let lsCfg = GM_getValue('tampOssCfg7n')
if (!lsCfg) return Promise.resolve(true)
lsCfg = typeof lsCfg === 'string' ? JSON.parse(lsCfg) : lsCfg
const oss = new TinyOSS(lsCfg.ossParams)
const lastTime = Date.now()
const data = name === 'state' ? {lastTime} : this.getAllCfg()
const blob = new Blob([JSON.stringify(data)], { type: 'text/json' })
GM_setValue('tampCfgUpdateTime', lastTime)
return new Promise(async (resolve) => {
try {
await oss.put(`json/tamp-cfg/${name}.json`, blob, {
onprogress(e) {
if (e.total > 0) {
return resolve(true)
}
}
})
} catch (err) {
return resolve(false)
}
})
},
async updateCfgFromOss() {
const lsCfg = this.getOssCfg()
const gmLastTime = GM_getValue('tampCfgUpdateTime')
if (lsCfg) {
try {
const res = (await (await fetch(`${lsCfg.state}&t=${Date.now()}`)).json())
const { lastTime } = res
const now = Date.now()
if (
!gmLastTime ||
lastTime > gmLastTime ||
now - gmLastTime > 30e3
) {
const rCfg = await ((await fetch(`${lsCfg.cfg}&t=${Date.now()}`)).json())
this.updateJsonToGm(rCfg)
this.initAddedWebToTextArea()
GM_setValue('tampCfgUpdateTime', now)
}
} catch (err) {}
}
},
// 判断是否从远程更新
async judgeIsUpdateCfgFromOss() {
const gmTime = GM_getValue('pageRefreshTime')
const now = Date.now()
if (!gmTime || now - gmTime > 5000) {
GM_setValue('pageRefreshTime', now)
await this.updateCfgFromOss()
}
},
updateTextAreaValToGm() {
const gmArr = GM_listValues()
.filter(v => v.startsWith('_cfg_'))
.map(v => v.replace(/^_cfg_/, ''))
const cArr = this.allAddedStr.split('\n')
gmArr.forEach(v => {
if (!cArr.some(c => v === c)) {
GM_deleteValue(`_cfg_${v}`)
}
})
},
updateJsonToGm(obj) {
if (!obj) return
GM_listValues()
.filter(v => /^_gus_|^_cfg_/.test(v))
.forEach(v => {
GM_deleteValue(v)
})
for (let k in obj) {
GM_setValue(k, obj[k])
}
},
tgCfgDialog() {
this.dialog1s = !this.dialog1s
},
hdlViewAllSet() {
this.showAllSet = !this.showAllSet
},
// 导入配置
hdlImportCfg() {
this.$refs.inp_hide.click()
},
// 导出配置
hdlExportCfg() {
const res = this.getAllCfg()
vio.downloadText(JSON.stringify(res, null, 2), '1.json')
},
// 获取oss配置
getOssCfg() {
let lsCfg = GM_getValue('tampOssCfg7n')
if (!lsCfg) return
try {
return typeof lsCfg === 'string' ? JSON.parse(lsCfg) : lsCfg
} catch (err) {}
},
initOssVal() {
const lsCfg = this.getOssCfg()
if (lsCfg) {
this.tampCfgVal = JSON.stringify(lsCfg)
}
},
// 获取所有已配置的网站数据
getAllCfg() {
return GM_listValues()
.filter(v => /^_gus_|^_cfg_/.test(v))
.reduce((acc, v) => {
let gmVal = GM_getValue(v)
gmVal = typeof gmVal === 'string' && gmVal > 1 ? JSON.parse(gmVal) : gmVal
return {
...acc,
[v]: gmVal
}
}, {})
},
hdlUpFile(e) {
let file = e.target.files[0]
if (file) {
let reader = new FileReader()
reader.readAsText(file, 'utf-8')
reader.onload = async (evt) => {
try {
oUp = JSON.parse(evt.target.result)
this.updateJsonToGm(oUp)
if (!await this.saveJsonToOss('state')) {
alert('上传失败, 请选择其他网站重新上传')
return
}
await this.saveJsonToOss('cfg')
this.initCssJsVal()
this.initAddedWebToTextArea()
this.initAddedScript()
this.initGMStyleClass()
setTimeout(() => {
location.reload()
}, 200)
} catch (e) {
// 上传失败
}
}
}
},
async resetCss() {
this.texCssVal = ''
this.disCSS = false
this.setGmVal({
...this.getGmVal(),
css: '',
disCSS: false,
})
await this.saveJsonToOss('state')
await this.saveJsonToOss('cfg')
location.reload()
},
async resetJs() {
this.texJsVal = ''
this.disJS = false
this.setGmVal({
...this.getGmVal(),
js: '',
disJS: false,
})
await this.saveJsonToOss('state')
await this.saveJsonToOss('cfg')
location.reload()
},
initEvt() {
window.addEventListener('keydown', e => {
if (
!(/text|search|number|password|tel|url|email/.test(e.target.type)) &&
e.target.tagName !== 'TEXTAREA' &&
!e.altKey &&
!e.ctrlKey &&
e.key === this.eKey
) {
this.tgCfgDialog()
}
if (/esc/i.test(e.key)) {
this.dialog1s = false
}
})
},
initEkey() {
this.eKey = GM_getValue('_gus_keyboard') || ''
},
initCssJsVal() {
this.texCssVal = this.getGmVal().css || ''
this.texJsVal = this.getGmVal().js || ''
this.disCSS = !!this.getGmVal().disCSS
this.disJS = !!this.getGmVal().disJS
},
initAddedWebToTextArea() {
const gmArr = GM_listValues()
.filter(v => v.startsWith('_cfg_'))
.map(v => v.replace(/^_cfg_/, ''))
this.allAddedStr = gmArr.join('\n')
},
initAddedScript() {
let js = this.getGmVal().js
let isDisabled = this.getGmVal().disJS
if (js && !isDisabled) {
let st = document.createElement('script')
st.type = 'module'
st.textContent = js
document.body.appendChild(st)
}
},
initGMStyleClass() {
document.querySelectorAll('style').forEach(v => {
if (!/\w{8}(-\w{4}){3}-\w{12}/.test(v.id)) {
return
}
if (v.textContent.includes('sty9z1p52')) {
v.classList.add('sty9z1p52')
}
})
},
},
async mounted() {
this.initEvt()
this.initOssVal()
await this.judgeIsUpdateCfgFromOss()
this.initEkey()
this.initCssJsVal()
this.initAddedWebToTextArea()
this.initAddedScript()
this.initGMStyleClass()
},
})
// 规则 -gvze----------------
function isIgnHost() {
return G.hostIgnore.some(v => location.host.includes(v))
}
function isIgnLink(linkUrl) {
return G.linkIgnore.some(v => linkUrl?.includes(v))
}
function isBlank(el) {
return el.target === '_blank'
}
function hasSibling(el) {
return getSiblings(el).length > 1
}
function isStaticStart(linkUrl) {
return linkHost(linkUrl)?.startsWith('static')
}
function isGif(el) {
return !!el?.src.endsWith('.gif')
}
function H1InH2(url) {
if (!url) return false
const f_host = location.host.replace(/^([\w-]+\.[\w-]+)$/, 'www.$1')
const H1 = (f_host.match(/(?<=[\w-]+\.).+/) || [])[0]
const linkHost = isUrl(url) ? new URL(url).host : null
const H2 = linkHost ? linkHost.replace(/^([\w-]+\.[\w-]+)$/, 'www.$1').match(/(?<=[\w-]+\.).+/)[0] : ''
return H2.includes(H1)
}
function isAbsolutePath(url) {
return /^https?|^\/\//i.test(url)
}
function isLightbox(link) {
return Array.from(link.attributes).some(v => v.nodeName.includes('lightbox'))
}
function unLikeAdSize(img) {
const iw = img.offsetWidth
const ih = img.offsetHeight
return iw < 150 && ih < 50 || iw < 50 && ih < 150 || iw < 91 && ih < 91
}
function hasImgFlag(el) {
return el.matches('.added_fk')
}
// 内联a标签转换为inline-block
function setInlineBlock(link) {
if (getComputedStyle(link).display === 'inline') {
link.style.display = 'inline-block'
}
}
// 如果是static则设置为relative
function setEleAsRelative(el) {
if (getComputedStyle(el).position === 'static') {
el.style.position = 'relative'
}
}
// -gvze-------------------------------
function linkHost(url) {
return isUrl(url) ? new URL(url).host : null
}
function isLikeImgArea(el, iw, ih) {
const w = getComputedStyle(el).width.replace('px', '') - 0
const h = getComputedStyle(el).height.replace('px', '') - 0
return 20 >= Math.abs(iw - w) && 20 >= Math.abs(ih - h)
}
// 屏蔽疑似站外广告(a标签下的图片)
function hideAdSuspected() {
document.querySelectorAll('a > img').forEach(el => {
const link = el.parentElement
const linkUrl = link.getAttribute('href')
const iw = el.offsetWidth
const ih = el.offsetHeight
if (
H1InH2(linkUrl) &&
!isGif(el) ||
isIgnLink(linkUrl) ||
(!isGif(el) && !isAbsolutePath(linkUrl)) ||
isLightbox(link) ||
(!isGif(el) && isStaticStart(linkUrl))
) {
el.closest('.GM-yisi-Asd')?.classList.remove('GM-yisi-Asd')
el.classList.remove('added_fk')
}
if (
isIgnHost() ||
isIgnLink(linkUrl) ||
unLikeAdSize(el) ||
hasImgFlag(el) ||
H1InH2(el?.src) && !isGif() ||
isGif(el)) {
return
}
if (
isBlank(link) && !H1InH2(linkUrl) && isAbsolutePath(linkUrl) && !isStaticStart(linkUrl)
) {
el.classList.add('added_fk')
setInlineBlock(link)
const arr = TMK.getParentEls(el).reverse()
for (let [i, v] of arr.entries()) {
if (isLikeImgArea(v, iw, ih)) {
v.classList.add('GM-yisi-Asd')
if (getComputedStyle(v).position === 'static') {
v.style.position = 'relative'
}
break
}
}
}
})
}
function isUrl(str) {
return /^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?$/.test(str)
}
function getSiblings(el) {
return Array.from(el.parentNode.childNodes)
.filter(node => node !== el && node.nodeType === 1)
}
// 屏蔽body直接子元素疑似AD
function bodyCdYisiAd() {
document.querySelectorAll('body > div').forEach(el => {
if (el.style.position === 'fixed' && el.style.zIndex > 998) {
el.classList.add('GM-certain-Asd')
}
})
}
// 屏蔽div中含有script的疑似AD
function scriptInDiv() {
document.querySelectorAll('script').forEach(el => {
const pEl = el.parentElement
const pw = pEl.offsetWidth
const ph = pEl.offsetHeight
if (!/body|html/i.test(pEl.nodeName) && (pw < 355 || ph < 355) ) {
setEleAsRelative(pEl)
pEl.classList.add('GM-yisi-Asd')
}
})
}
// 屏蔽包含广告文字的box
function hideContainAdText() {
document.querySelectorAll('div[class*="ad" i],div[id*="ad" i],a[class*="ad" i],a[id*="ad" i],ul[class*="ad" i],ul[id*="ad" i]').forEach(v => {
if (![...v.classList].some(c => /\bads?|ads?(\b|$)/i.test(c))) return
if (!/广告(\b|$)/m.test(v.textContent)) return
v.classList.add('GM-certain-Asd', 'Asd-text')
})
}
// 屏蔽iframe疑似广告
function hideIfrYiSiAd() {
const regT = /\bads?|(?<!he)ads?(\b|$)/i
document.querySelectorAll('div[class*="ad" i],div[id*="ad" i],a[class*="ad" i],a[id*="ad" i],ul[class*="ad" i],ul[id*="ad" i]').forEach(el => {
if (
![...el.classList].some(c => regT.test(c)) &&
!regT.test(el.id)
) {
return
}
if (!TMK.getChildEls(el).some(c => c.nodeName === 'IFRAME') && el.nodeName !== 'IFRAME') return
el.classList.add('GM-yisi-Asd')
})
}
// 屏蔽iframe广告
function hideIfrCertainAd() {
document.querySelectorAll('iframe').forEach(v => {
if (G.ifrIgnore.some(c => v.src?.includes(c))) return
if (
!/^https?|^\/\/|^javascript/i.test(v?.src) &&
!Array.from(v.attributes).some(e2 => e2.value.includes('baidu'))
) return
if (
v.offsetWidth > 320 &&
v.offsetHeight > 320 ||
v.offsetWidth < 40 &&
v.offsetHeight < 40
) {
return
}
const pEl = v.parentElement
if (!/body|html/i.test(pEl.tagName)) {
if (getSiblings(v).length > 1) {
v.classList.add('GM-certain-Asd')
} else {
pEl.classList.add('GM-certain-Asd')
}
}
setEleAsRelative(pEl)
})
}
function initBlockFunc() {
const fn = initBlockFunc
fn.count = fn.count || 0
fn.count++
// 屏蔽疑似站外广告
hideAdSuspected()
bodyCdYisiAd()
// 屏蔽包含广告文字的box
hideContainAdText()
// 屏蔽iframe广告
hideIfrCertainAd()
// 屏蔽疑似iframe广告
hideIfrYiSiAd()
scriptInDiv()
if (fn.count < 80) {
setTimeout(fn, 200)
}
}
const initFunc = () => {
if (!vio.isMobile()) {
document.addEventListener('DOMContentLoaded', () => {
document.body.insertAdjacentHTML('beforeend', G.html)
vm.$mount('#wp5sn')
GM_registerMenuCommand('打开设置面板', vm.tgCfgDialog)
GM_registerMenuCommand('清空当前网站添加的CSS', vm.resetCss)
GM_registerMenuCommand('清空当前网站添加的JS', vm.resetJs)
initBlockFunc()
}, false)
window.addEventListener('mousemove', vio.throttle(() => {
hideAdSuspected()
}, 3000))
}
}
initFunc()