// ==UserScript== // @name Hostloc根据关键字和用户名屏蔽帖子 // @namespace https://hostloc.com/ // @version 0.2.5 // @description 根据关键字和用户名屏蔽帖子,根据用户名屏蔽签名 // @author kiwi // @homepage https://github.com/FlyxFly/hostloc-block-post-and-signature // @match https://hostloc.com/forum-* // @match https://hostloc.com/thread-* // @match https://hostloc.com/forum.php?mod=viewthread&tid=* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @require https://unpkg.com/sweetalert/dist/sweetalert.min.js // @downloadURL none // ==/UserScript== (function() { 'use strict'; const now = function(){ return new Date().getTime(); } // 移除数组中的空元素 if(!Array.prototype.trim){ Array.prototype.trim = function removeEmptyElements () { return this.filter((x)=>{ return x; }) } } // 查询数组是否存在某个值,忽略大小写 if(!Array.prototype.contains){ Array.prototype.contains = function checkIfInArray (target) { for(let i=0;i 12*3600*1000){ return this.modifyCloudData('get'); } } for (let x in this.dataKeys) { const key = this.dataKeys[x]; this.config[key]=jsonData.data[key]; } } } async modifyCloudData(action){ if(!this.config.pantry.APIKey || !this.config.pantry.basket){ return false; } const url = `https://getpantry.cloud/apiv1/pantry/${this.config.pantry.APIKey}/basket/${this.config.pantry.basket}`; switch(action){ case 'get': fetch(url,{ method:'GET', headers: { 'Content-Type': 'application/json' }, }) .then((response)=>response.json()) .then((data)=>{ this.config = data; this.saveToLocal(); this.restoreFromLocal(); this.startBlockProcess(); console.log('Got data from cloud.',data); }) break; case 'save': swal('正在保存到云端,请勿跳转到其他页面.'); fetch(url, { method:'POST', headers: { 'Content-Type': 'application/json' }, body:JSON.stringify(this.config) }).then((res)=>{ swal('数据保存到云端成功','你可以跳转到其他页面了','success'); console.log('Save data to cloud',res); }).catch((e)=>{ swal('数据保存到云端失败',e.message,'error'); }) break; default: return false; } } hideFromList(){ const blockedKeyword = this.config.blockedKeyword; const blockedUser = this.config.blockedUser; document.querySelectorAll('#threadlisttableid tbody').forEach((item,index)=>{ if(item.id.includes('normalthread')){ const title=item.querySelector('a.s.xst').innerText; for (let i = blockedKeyword.length - 1; i >= 0; i--) { if(title.toUpperCase().includes(blockedKeyword[i].toUpperCase())){ // item.querySelector('a.s.xst').innerText='已屏蔽'; item.style.display='none'; break; } } const nameA=item.querySelectorAll('td.by')[0].querySelector('a'); if(nameA){ const userName=nameA.innerText.trim().toUpperCase(); if(blockedUser.contains(userName)){ // item.querySelector('a.s.xst').innerText='已屏蔽'; item.style.display='none'; } } } }) } hideReplyAndSignature(){ const blockedSignatureUser = this.config.blockedSignatureUser; const blockedKeyword = this.config.blockedKeyword; const contentStorage = this.contentStorage; const blockedUser = this.config.blockedUser; document.querySelectorAll('#postlist>div').forEach((post)=>{ if(!post.id.includes('post_')){ return false; } const userLink=post.querySelector('a.xw1'); if(userLink){ const userName=userLink.innerText.trim(); // 根据用户名屏蔽发帖 if(userName && blockedUser.includes(userName)){ post.style.display='none'; return false; } // 根据用户名屏蔽签名 if(blockedSignatureUser.includes(userName) && post.querySelector('div.sign')){ const signature=post.querySelector('div.sign'); const contentText=signature.innerText; const contentHTML=signature.innerHTML; const storageKey=post.id+'signature'; contentStorage[storageKey]=contentHTML; signature.innerHTML=`已屏蔽,鼠标移到此处查看内容,点击还原内容`; } } const tds=post.querySelectorAll('td'); tds.forEach((td)=>{ // 查找帖子内容容器: td.postmessage_{thread_id} if(td.id.includes('postmessage_')){ const content=td.innerText; for (let i = blockedKeyword.length - 1; i >= 0; i--) { // 根据关键字屏蔽发帖内容 if(content.toUpperCase().includes(blockedKeyword[i].toUpperCase())){ const contentHTML=td.innerHTML; const contentText=td.innerText; contentStorage[post.id]=contentHTML; td.innerHTML=`已屏蔽,鼠标移到此处查看内容,点击还原内容`; break; } } } }) }) } addSettingButton(){ const p = document.querySelectorAll('#um p')[1]; p.appendChild(htmlToElement(`|`)); p.appendChild(htmlToElement(`屏蔽名单设置`)); } addSettingPanel(){ const div = document.createElement('div'); div.id='hostloc-blocker-panel-wrapper'; div.innerHTML = ` Document `; document.body.appendChild(div); } addPanelEvents(){ const panel = document.querySelector('#hostloc-blocker-panel'); const saveButton = panel.querySelector('.save'); const inputPantryAPIKey = panel.querySelector('[name="pantry-api-key"]'); const inputBasketName = panel.querySelector('[name="pantry-basket-name"]'); const textareaBlockedUser = panel.querySelector('textarea[name="blocked-user"]'); const textareaBlockedSignatureUser = panel.querySelector('textarea[name="blocked-signature-user"]'); const textareaBlockedKeyword = panel.querySelector('textarea[name="blocked-keyword"]'); const openPanelLink = document.querySelector('#show-block-panel'); panel.addEventListener('click',(event)=>{ event.stopPropagation(); }) document.body.addEventListener('click',()=>{ panel.classList.remove('is-active'); }) openPanelLink.addEventListener('click',(event)=>{ event.stopPropagation(); textareaBlockedKeyword.value = this.config.blockedKeyword.join('\n'); textareaBlockedSignatureUser.value = this.config.blockedSignatureUser.join('\n'); textareaBlockedUser.value = this.config.blockedUser.join('\n'); inputPantryAPIKey.value = this.config.pantry.APIKey; inputBasketName.value = this.config.pantry.basket; panel.classList.add('is-active'); }); saveButton.addEventListener('click',()=>{ this.config.pantry.APIKey = inputPantryAPIKey.value; this.config.pantry.basket = inputBasketName.value; // 如果仅输入了apikey 则表示从云端拉取数据,将覆盖本地数据 if(!textareaBlockedKeyword.value && !textareaBlockedSignatureUser.value && !textareaBlockedUser.value){ this.modifyCloudData('get'); return; }else{ // 将api key 和数据保存到本地 this.config.blockedKeyword = textareaBlockedKeyword.value.split('\n').trim(); this.config.blockedSignatureUser = textareaBlockedSignatureUser.value.split('\n').trim(); this.config.blockedUser = textareaBlockedUser.value.split('\n').trim(); // 保存到本地 this.saveToLocal(); // 将数据保存到云端 this.modifyCloudData('save'); } panel.classList.remove('is-active'); }) } startBlockProcess(){ if(location.href.includes('forum')){ this.hideFromList(); } if(location.href.includes('thread')){ this.hideReplyAndSignature(); } //监听点击事件,恢复被屏蔽的签名和帖子 if(location.href.includes('thread')){ document.querySelector('#postlist').addEventListener('click',(e)=>{ const item=e.target; if(item.className.includes('hidden-by-script')){ item.innerHTML=this.contentStorage[item.dataset.restoreKey]; item.title=''; item.style=''; } }) } } init(){ this.addSettingPanel(); this.addSettingButton(); this.addPanelEvents(); this.restoreFromLocal(); this.startBlockProcess(); } } const app=new HostLocBlocker(); app.init(); })();