您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Your own censor list for 4chan
// ==UserScript== // @name Replace and highlight // @namespace wordreplace // @version 2015.08.21 // @include *://boards.4chan.org/* // @grant unsafeWindow // @grant GM_getValue // @grant GM_setValue // @description Your own censor list for 4chan // ==/UserScript== 'use strict'; // Create element function function element(){ var parent var toreturn={} for(var i=0;i<arguments.length;i++){ var current=arguments[i] if(current.nodeType){ parent=current }else{ if(Array.isArray(current)){ var tagname=current[0].split('#') var newtag=document.createElement(tagname[0]) if(tagname[1]){ toreturn[tagname[1]]=newtag } for(var j=1;j<current.length;j++){ if(current[j].constructor==Object){ for(var value in current[j]){ if(value!='style'&&value in newtag){ newtag[value]=current[j][value] }else{ newtag.setAttribute(value,current[j][value]) } } }else{ var returned=element(newtag,current[j]) for(var k in returned){ toreturn[k]=returned[k] } } } }else{ var newtag=document.createTextNode(current) } if(parent){ parent.appendChild(newtag) } } } return toreturn } //Update posts function updateposts(event){ if(event){ var replies=document.querySelectorAll('#t'+event.detail.threadId+' .postContainer:not(.wordreplace)') }else{ var replies=document.querySelectorAll('.thread .postContainer:not(.wordreplace)') } if(replies.length){ if(replies.length>200){ var end=200 }else{ var end=replies.length } for(var i=0;i<end;i++){ if(i==200){ var j=0 }else{ var j=i } replies[j].classList.add('wordreplace') //Remove wbr tags if(thesettings.wrremwbr){ var wbr=replies[j].getElementsByTagName('wbr') for(var k=wbr.length;k--;){ var pre=wbr[k].previousSibling var nex=wbr[k].nextSibling if(pre&&nex&&pre.nodeType==3&&nex.nodeType==3){ pre.nodeValue+=nex.nodeValue nex.parentNode.removeChild(nex) } wbr[k].parentNode.removeChild(wbr[k]) } } //Replace and highlight wordreplacing(replies[j]) } } } //Add new settings function updatesettings(){ setTimeout(function(){ unsafeWindow.SettingsMenu.options['Replace and highlight']={ wordreplace:['Replace and highlight words [<a href="javascript:wordreplace()">Edit</a>]','Your own censor list',1], wronlyin:['Instead of replacing everything, replace only in:','',1], wrbody:['Comment body','',1,1], wrsubject:['Subject','',1,1], wrfilename:['Filename','',1,1], wrposter:['Poster name','',0,1], wrtitle:['Page title','',1,1], wrremwbr:['Remove all <wbr> tags from the posts','<wbr> tags are inserted every 35 characters in long words, which may prevent some patterns from working',1], wrtooltip:['Reveal original line in a tooltip when hovered over','',0] } unsafeWindow.wordreplace=function(event,action){ var norefresh=0 var order={on:1,pattern:0,case:1,replace:0,js:1,caps:1,mark:1,board:0} if(!action){ wr_temp=JSON.parse(JSON.stringify(wr_strings)) var menu=element( document.body, ['div',{ class:'UIPanel', id:'wr-body', onclick:closepanel }, ['div',{ class:'extPanel reply', style:'width:600px;margin-left:-300px' }, ['div',{ class:'panelHeader' }, 'Replace and highlight words', ['span', ['img',{ alt:'Close', title:'Close', class:'pointer', src:unsafeWindow.Main.icons.cross }] ] ], ['table',{ style:'text-align:center' }, ['thead', ['tr', ['th'], ['th','On'], ['th','Pattern'], ['th','Case'], ['th','Replace'], ['th','JS'], ['th','Caps'], ['th','Mark'], ['th','Board'], ['th','Del'] ] ], ['tbody',{ id:'wr-list' }], ], ['div',{ style:'float:left' }, ['input',{ type:'button', value:'Add', onclick:function(event){ wordreplace(event,'add') } }], ['input',{ type:'button', value:'Import/Export', onclick:function(event){ wordreplace(event,'port') } }] ], ['div',{ style:'float:right' }, ['input',{ type:'button', value:'Save', onclick:function(event){ wordreplace(event,'save') } }], ['input',{ type:'button', value:'Save and close', onclick:function(event){ wordreplace(event,'save') document.getElementById('wr-body').click() } }] ], ['table',{ style:'width:100%' }, ['tr',{ style:'vertical-align:top' }, ['td', ['textarea#input',{ id:'wr-input', paceholder:'Test it here', style:'width:280px;height:50px' }] ], ['td',{ style:'vertical-align:top;text-align:left' }, ['div',{ id:'wr-output', style:'width:294px;word-wrap:break-word;overflow:hidden' }] ] ] ] ], ['style','\ #wr-body input[type="text"],#wr-body .wr-replace{\ font:13px monospace;\ width:135px;\ }\ #wr-body .wr-board{\ width:60px!important;\ }\ #wr-body textarea.wr-replace{\ height:50px;\ resize:none!important;\ overflow:hidden;\ cursor:text;\ }\ #wr-body [error],#wr-body .js{\ vertical-align:top;\ }\ #wr-body [error]::after{\ content:attr(error);\ display:block;\ position:absolute;\ overflow:hidden;\ left:0;\ text-overflow:ellipsis;\ width:100%;\ white-space:nowrap;\ margin-top:25px;\ height:20px;\ font-size:12px;\ color:#d00\ }\ #wr-body [error] .wr-replace{\ margin-bottom:20px!important;\ }\ #wr-body .js[error]::after{\ margin-top:60px;\ }'] ] ) menu.input.onkeydown=menu.input.onkeyup=menu.input.onchange=menu.input.onclick=function(event){ wordreplace(event,'type') } } var list=document.getElementById('wr-list') var trs=list.getElementsByTagName('tr') if(action!='imported'){ for(var i=0;i<wr_temp.length;i++){ if(trs[i]){ for(var j in order){ var input=trs[i].getElementsByClassName('wr-'+j)[0] if(order[j]){ wr_temp[i][j]=input.checked }else{ wr_temp[i][j]=input.value } } } } } switch(action){ case 'add':{ wr_temp.push({on:1,caps:1}) break } case 'up':{ var id=event.target.parentNode.parentNode.id.match(/filter-(\d+)/)[1]*1 if(id>0){ var temp=wr_temp[id] wr_temp[id]=wr_temp[id-1] wr_temp[id-1]=temp }else{ norefresh=1 } break } case 'del':{ var id=event.target.parentNode.parentNode.id.match(/filter-(\d+)/)[1]*1 wr_temp.splice(id,1) break } case 'save':{ for(var i=wr_temp.length;i--;){ if(!wr_temp[i].pattern&&!wr_temp[i].replace){ wr_temp.splice(i,1) } } wr_strings=wr_temp.slice() GM_setValue('wordreplace',JSON.stringify(wr_temp)) norefresh=1 break } case 'type': case 'imported':{ var input=document.getElementById('wr-input').value input=input.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/(>>\d+|>>>\/\w+\/\d*)/g,'<a class="quotelink pointer">$1</a>').replace(/\n/g,'<br>').replace(/\[(\/)?spoiler\]/g,'<$1s>').replace(/^(>[^\n]*)$/gm,'<span style="color:#789922">$1</span>') var output=document.getElementById('wr-output') output.innerHTML=input output.classList.remove('replacedtext') wordreplacing(output,1,wr_temp) if(action!='imported'&&!event.target.classList.contains('wr-js')){ norefresh=1 } break } case 'port':{ var port=element( document.body, ['div#panel',{ class:'UIPanel', onclick:closepanel }, ['div',{ class:'extPanel reply', style:'text-align:center' }, ['div',{ class:'panelHeader' }, 'Import/Export patterns', ['span', ['img',{ alt:'Close', title:'Close', class:'pointer', src:unsafeWindow.Main.icons.cross }] ] ], ['textarea#txt',{ style:'width:100%;height:100px;box-sizing:border-box', value:JSON.stringify(wr_temp) }], ['div',{ style:'float:left' }, ['input',{ type:'button', value:'Save to file', onclick:function(){ var txt=port.txt.value txt=btoa(encodeURIComponent(txt).replace(/%([0-9A-F]{2})/g,function(a,b){ return String.fromCharCode('0x'+b) })) element( ['a#link',{ href:'data:application/json;base64,'+txt, download:'wordreplace.json' }] ).link.click() } }], ['input',{ type:'button', value:'Load from file', onclick:function(){ port.file.click() } }], ], ['div',{ style:'float:right' }, ['input',{ type:'button', value:'Replace all', onclick:function(event){ var temp try{ temp=fromimport(JSON.parse(port.txt.value)) }catch(e){ alert('This is not a valid JSON') } if(temp){ wr_temp=temp wordreplace(event,'imported',1) port.panel.click() } } }], ['input',{ type:'button', value:'Import and append', onclick:function(event){ var temp try{ temp=fromimport(JSON.parse(port.txt.value)) }catch(e){ alert('This is not a valid JSON') } if(temp){ wr_temp=wr_temp.concat(temp) wordreplace(event,'type',1) port.panel.click() } } }] ], ['form', ['input#file',{ type:'file', style:'display:none', onchange:function(event){ if(event.target.files.length){ var reader=new FileReader() reader.onload=function(read){ port.txt.value=read.target.result event.target.parentNode.reset() } reader.readAsText(event.target.files[0]) } } }] ] ] ] ) norefresh=1 break } case 'editjs':{ var target=event.target var editor=element( document.body, ['div',{ class:'UIPanel', id:'wr-body', onclick:function(event){ if(event.target.className=='UIPanel'||event.target.tagName=='IMG'){ target.value=editor.txt.value closepanel(event) wordreplace(event,'type') } } }, ['div',{ class:'extPanel reply', style:'width:600px;margin-left:-300px' }, ['div',{ class:'panelHeader' }, 'Edit function', ['span', ['img',{ alt:'Close', title:'Close', class:'pointer', src:unsafeWindow.Main.icons.cross }] ] ], ['textarea#txt',{ value:target.value, onkeydown:function(event){ if(event.keyCode==9){ //Tab event.preventDefault() var input=event.target var start=input.selectionStart input.value=input.value.slice(0,start)+'\t'+input.value.slice(input.selectionEnd) input.setSelectionRange(start+1,start+1) } }, style:'width:100%;height:500px;box-sizing:border-box;font:13px monospace' }] ] ] ) editor.txt.setSelectionRange(0,0) norefresh=1 break } } if(!norefresh){ list.innerHTML='' if(!wr_temp.length){ wr_temp=[{on:1,caps:1}] } for(var i in wr_temp){ var table=element( list, ['tr#tr',{ id:'filter-'+i }, ['td', ['span',{ class:'pointer', onclick:function(event){ wordreplace(event,'up') } },'\u2191'] ] ] ) for(var j in order){ var tagname='input' var js=j=='replace'&&wr_temp[i].js if(js){ tagname='textarea' } var td=element( table.tr, ['td', [tagname+'#input',{ class:'wr-'+j, onchange:function(event){ wordreplace(event,'type') } }] ] ) if(order[j]){ td.input.type='checkbox' if(j=='on'&&wr_temp[i][j]==undefined){ td.input.checked=1 }else{ td.input.checked=wr_temp[i][j] } }else{ if(js){ table.tr.classList.add('js') td.input.readOnly=1 td.input.onclick=function(event){ wordreplace(event,'editjs') } }else{ td.input.type='text' } td.input.value=wr_temp[i][j]||'' } } element( table.tr, ['td', ['span',{ class:'pointer', onclick:function(event){ wordreplace(event,'del') } },'\xD7'] ] ) } } for(var i in wr_temp){ var errors=[] try{ var a=RegExp(wr_temp[i].pattern) }catch(e){ errors.push('Error in regex: '+e.message.replace(/.*:.*: /,'')) } if(wr_temp[i].js){ try{ eval('!function(){'+wr_temp[i].replace+'}') }catch(e){ errors.push('Error in function: '+e.message) } } if(errors.length){ document.getElementById('filter-'+i).setAttribute('error',errors.join(' | ')) }else{ document.getElementById('filter-'+i).removeAttribute('error') } } } },1000) } function closepanel(event){ if(event.target.className=='UIPanel'){ event.target.parentNode.removeChild(event.target) } if(event.target.tagName=='IMG'){ var target=event.target.parentNode.parentNode.parentNode.parentNode target.parentNode.removeChild(target) } } function fromimport(json){ var order={on:1,pattern:0,case:1,replace:0,js:1,caps:1,mark:1,board:0} try{ if(json.patterns){ json=json.patterns } var temp=[] for(var i in json){ temp[i]={} for(var j in order){ if(json[i][j]==undefined){ if(j=='on'||j=='caps'){ temp[i][j]=1 }else{ if(order[j]){ temp[i][j]=0 }else{ temp[i][j]='' } } }else{ temp[i][j]=json[i][j] } } } return temp }catch(e){ alert('This JSON cannot be imported because it is corrupt') console.log(e.message) } } //Word replace function wordreplacing(post,main,strings){ if(!post||!post.classList){ return } if(post.classList.contains('replacedtext')){ return } post.classList.add('replacedtext') if(main){ var comments=[post] }else{ var props=[] if(thesettings.wronlyin){ if(thesettings.wrbody){ props.push('blockquote') } if(thesettings.wrsubject){ props.push('.subject') } if(thesettings.wrfilename){ props.push('.fileText>a') } if(thesettings.wrposter){ props.push('.nameBlock') } }else{ props=['.nameBlock','.fileText>a','.subject','blockquote'] } if(!props.length){ return } var comments=post.querySelectorAll(props.join(',')) } for(var i=0;i<comments.length;i++){ var textnodes=[] var walk=document.createTreeWalker(comments[i],4,null,0) var newnode while(newnode=walk.nextNode()){ textnodes.push(newnode) } for(var j in textnodes){ var currentnode=textnodes[j] var out=teststring(currentnode.nodeValue.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'),strings) if(out!=null){ if(thesettings.wrtooltip||/[<>]/.test(out)){ var newspan=element( ['span#span',{ innerHTML:out }] ) if(thesettings.wrtooltip){ newspan.span.title=currentnode.nodeValue } currentnode.parentNode.insertBefore(newspan.span,currentnode) currentnode.parentNode.removeChild(currentnode) }else{ currentnode.nodeValue=out.replace(/>/g,'>').replace(/</g,'<').replace(/&/g,'&') } } } } } function teststring(text,replaces){ if(text.length){ var oldtext=text if(replaces){ var patterns=replaces }else{ var patterns=wr_strings } for(var i in patterns){ try{ if( patterns[i].on&& patterns[i].pattern&&( !patterns[i].board|| patterns[i].board.toLowerCase().replace(/[,;]/g,' ').replace(/[^a-z\d\s]/g,'').trim().split(/\s+/).indexOf(currentboard)+1 ) ){ var replacewith=patterns[i].replace+'' if(patterns[i].js){ replacewith=function(){ return eval('(function(){'+patterns[i].replace+'}).apply(undefined,arguments)') } }else if(patterns[i].mark){ replacewith='<span class="highlighttext">'+(replacewith||'$&')+'</span>' } if(patterns[i].caps){ var replacestring=replacewith replacewith=function(){ if(patterns[i].js){ var returned=replacestring.apply(undefined,arguments) var s=[returned,arguments[0]] }else{ var args=arguments var s=[replacestring,args[0]] s[0]=s[0].replace(/\$&/g,'$$0').replace(/\$(\d+)/g,function(){ var num=arguments[1]*1 return args[num]||'' }) } var al=s[0].length var bl=s[1].length if(al>bl){ var l=bl }else{ var l=al } if(l<2){ return s[0] } s=s.map(function(a){ return [a.slice(0,l-l/2),a.slice(l-l/2,-l/2),a.slice(-l/2)] }) for(var j=0;j<3;j+=2){ s[0][j]=s[0][j].toLowerCase().split('') for(var k=0;k<s[0][j].length;k++){ var c=s[1][j][k] if(c==c.toUpperCase()&&c!=c.toLowerCase()){ s[0][j][k]=s[0][j][k].toUpperCase() } } s[0][j]=s[0][j].join('') } if(s[0][1]){ var u=0 if(s[1][1]){ var c=s[1][1] if(c==c.toUpperCase()&&c!=c.toLowerCase()){ u=2 } }else{ var c=s[1][0][(l/2|0)-1] if(c==c.toUpperCase()){ u++ } var c=s[1][2][0] if(c==c.toUpperCase()){ u++ } } if(u==2){ s[0][1]=s[0][1].toUpperCase() } } return s[0].join('') } }else if(!patterns[i].js){ replacewith=replacewith.replace(/\$0/g,'$$&') } var ig=patterns[i].case?'g':'ig' text=text.replace(new RegExp(patterns[i].pattern,ig),replacewith) } }catch(e){ if(!replaces){ wr_strings[i].on=0 } console.error('Error in regex: '+patterns[i].pattern,',',e.message) } } if(oldtext!=text){ return text }else{ return null } }else{ return null } } if(document.getElementsByTagName('meta').length){ //Get settings var thesettings=localStorage['4chan-settings'] var thedefault='wordreplace wronlyin wrbody wrsubject wrfilename wrtitle wrremwbr'.split(' ') if(thesettings){ thesettings=JSON.parse(thesettings) var changed=0 for(var i in thedefault){ if(thesettings[thedefault[i]]==undefined){ thesettings[thedefault[i]]=true changed=1 } } if(changed){ localStorage['4chan-settings']=JSON.stringify(thesettings) } }else{ thesettings={} var gmsetting=GM_getValue('wordreplace') if(gmsetting){ thesettings.wordreplace=gmsetting=='true'?1:0 } } //Determine current page format, board name, and thread id if(document.body.classList.contains('is_index')){ var activepage='index' }else if(document.getElementById('content')){ var activepage='catalog' }else if(location.pathname.indexOf('/thread/')+1){ var activepage='thread' }else{ var activepage='main' } var currentboard='' var match=document.body.classList[0] if(match){ match=match.match(/^board_(\w+)$/) if(match){ var currentboard=match[1] }else if(activepage!='main'){ match=location.pathname.match(/^\/(\w+)\//) if(match){ var currentboard=match[1] } } } //Retrieve pattern list var wr_strings=GM_getValue('wordreplace') if(wr_strings){ wr_strings=JSON.parse(wr_strings) }else{ wr_strings=[ { on:1, pattern:'newfag', case:0, replace:'newfig', js:0, caps:1, mark:0, board:'s4s' }, { on:1, pattern:'shitpost', case:0, replace:'funpost', js:0, caps:1, mark:0, board:'s4s' } ] } var wr_temp if(thesettings.wordreplace&&(thesettings.wrtitle||!thesettings.wronlyin)){ var newtitle=teststring(document.title.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')) if(newtitle!=null){ document.title=newtitle.replace(/[\r\n]/g,'').replace(/<[^>]*>/g,'').replace(/>/g,'>').replace(/</g,'<').replace(/&/g,'&') } } if(activepage=='index'||activepage=='thread'){ if(thesettings.wordreplace){ updateposts() document.addEventListener('4chanParsingDone',updateposts) } if(unsafeWindow.Main){ updatesettings() }else{ document.addEventListener('4chanMainInit',updatesettings) } } if(activepage=='catalog'&&thesettings.wordreplace){ for(var i in unsafeWindow.catalog.threads){ var props=[] if(thesettings.wronlyin){ if(thesettings.wrbody){ props.push('teaser') } if(thesettings.wrsubject){ props.push('sub') } if(thesettings.wrfilename){ props.push('file') } if(thesettings.wrposter){ props.push('author') } }else{ props=['author','file','sub','teaser'] } props.forEach(function(prop){ var out=teststring(unsafeWindow.catalog.threads[i][prop]) if(out!=null){ unsafeWindow.catalog.threads[i][prop]=out } if(prop=='author'&&unsafeWindow.catalog.threads[i].lr.author){ var out=teststring(unsafeWindow.catalog.threads[i].lr.author) if(out!=null){ unsafeWindow.catalog.threads[i].lr.author=out } } }) } document.getElementById('size-ctrl').dispatchEvent(new Event('change')) } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址