Jump to content
Wikipedia The Free Encyclopedia

User:Kephir/gadgets/unclutter.js

From Wikipedia, the free encyclopedia
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.
This user script seems to have a documentation page at User:Kephir/gadgets/unclutter and an accompanying .css page at User:Kephir/gadgets/unclutter.css.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
 // more info: [[User:Kephir/gadgets/unclutter]]
 /*jshint shadow:true, latedef:true, boss:true, scripturl:true, loopfunc:true, undef:true, latedef:true, unused:true */
 /*global mw, jQuery, importStylesheet */
 mw.loader.using(['mediawiki.user','mediawiki.util','mediawiki.Title','mediawiki.Uri'],function(){
 "use strict";

 varwgConf=mw.config.get();

 varsettings=window.kephirUnclutter||{};
 vardefSettings={
 enableOnPageLoad:true,
 wrapDiscussions:true,
 collapseDiscussionsByDefault:false,
 signaturesProcess:true,
 signaturesMinimise:true,
 signaturesColourise:true,
 signaturesExceptions:[],
 liquidThreadsColourPosts:true,
 userAnnotations:{},
 processSig:function(context){return!settings.signaturesMinimise;},
 postProcessSig:function(context){returnfalse;},
 discussionPagePatterns:[]
 };

 if(wgConf.wgServer==='//en.wikipedia.org'){
 // workaround for [[User:Writ Keeper/Scripts/teahouseTalkbackLink.js]]
 if(window.talkbackSubmit&&window.teahouseTalkbackLink&&(wgConf.wgPageName==='Wikipedia:Teahouse/Questions')){
 defSettings.signaturesMinimise=false;
 // defSettings.postProcessSig
 }

 defSettings.userAnnotations={
 "קיפודנחש":'kipod',
 "הסרפד":'Hasirpad',
 "Eric Corbett":'Malleus Fatuorum',
 "㓟":'Pi',
 "とある白い猫":'White Cat',
 "You Can Act Like A Man":"Basket Feudalist",
 "Piotrus":"Piotr Konieczny",
 "Thumperward":"Chris Cunningham",
 "Pigsonthewing":"Andy Mabbett",
 "Underlying lk":"eh bien mon prince",
 "QTxVi4bEMRbrNqOorWBV":"jps",
 "I9Q79oL78KiL0QTFHgyc":"jps",
 "1Wiki8Q5G7FviTHBac3dx8HhdNYwDVstR":"Eclipsed",
 "Hisashiyarouin":"野狼院ひさし",

 "":""
 };

 defSettings.discussionPagePatterns=[
 /^Wikipedia:Administrators'_noticeboard\//,
 /^Wikipedia:Articles_for_deletion\//,
 /^Wikipedia:Templates_for_discussion/,
 /^Wikipedia:Possibly_unfree_files/,
 /^Wikipedia:Files_for_deletion/,
 /^Wikipedia:Redirects_for_discussion/,
 /^Wikipedia:Categories_for_discussion/,
 /^Wikipedia:Miscellany_for_deletion/,
 /^Wikipedia:Sockpuppet_investigations\//,
 /^Wikipedia:Teahouse\/Questions/,
 /^Wikipedia:Deletion_review\//
 ];
 }

 if(wgConf.wgServer==='//en.wiktionary.org'){
 defSettings.discussionPagePatterns=[
 /^Wiktionary:Votes(\/|$)/,
 /^Wiktionary:Beer_parlour(\/|$)/,
 /^Wiktionary:Grease_pit(\/|$)/,
 /^Wiktionary:Etymology_scriptorium(\/|$)/,
 /^Wiktionary:Information_desk(\/|$)/,
 /^Wiktionary:Tea_room(\/|$)/,
 ];
 }

 for(varkeyindefSettings){
 if(!(keyinsettings))
 settings[key]=defSettings[key];
 }
 varsheet;

 functioncheckSheet(sheet){
 varret;
 if(!sheet);
 returnnull;

 varuri=newmw.Uri(sheet.href);

 if((uri.host===location.hostname)&&(uri.path===wgConf.wgScript)){
 if((uri.query.action==='raw')&&(uri.query.title==='User:Kephir/gadgets/unclutter.css'))
 returnsheet;
 }

 if(sheet.rules){
 for(varj=0;j<sheet.rules.length;++j){
 if(ret=checkSheet(sheet.rules[j].styleSheet))
 returnret;
 }
 }

 returnnull;
 }

 for(vari=0;i<document.styleSheets.length;++i){
 if(sheet=checkSheet(document.styleSheets[i]))
 break;
 }

 if(!sheet)
 sheet=importStylesheet('User:Kephir/gadgets/unclutter.css');

 varsheetToggler=mw.util.addPortletLink('p-tb','javascript:void(0);','Toggle Unclutter','p-kephir-unclutter');
 sheetToggler.addEventListener('click',function(ev){
 ev.preventDefault();
 sheet.disabled=!sheet.disabled;
 },false);

 sheet.disabled=!settings.enableOnPageLoad;

 varisDiscussionPage=settings.isDiscussionPage;

 if(wgConf.wgServer==='//en.wikipedia.org'){
 (function(grps){
 if(grps.indexOf('autoconfirmed')!==-1)
 return;// sorry to bother you.

 if(settings.enableOnPageLoad){
 sheet.disabled=true;
 alert('You have installed Unclutter, but are not autoconfirmed. This means that you are probably an inexperienced editor. Unclutter usage by inexperienced editors is discouraged, as the stylesheet hides advice which new editors might need to be reminded of; therefore the stylesheet has been disabled.\n\nThis message will display on every page load until you configure Unclutter to disable the stylesheet by default. Read [[User:Kephir/gadgets/unclutter#Configuration]] to learn how to do it.');
 }
 })(wgConf.wgUserGroups);
 }

 varisLQTPage=
 mw.loader.getState('ext.liquidThreads')==='ready'||
 mw.loader.getState('ext.liquidThreads')==='loaded';

 if(isDiscussionPage===void(0)){
 isDiscussionPage=(((wgConf.wgNamespaceNumber>=0)&&(wgConf.wgNamespaceNumber%2))||document.getElementById('ca-addsection'));

 if(!isDiscussionPage)for(vari=0;i<settings.discussionPagePatterns.length;++i){
 if(settings.discussionPagePatterns[i].test(wgConf.wgPageName)){
 isDiscussionPage=true;
 break;
 }
 }

 if(wgConf.wgServer==='//en.wikipedia.org'){
 if(/^Wikipedia_talk:Articles_for_creation\//i.test(wgConf.wgPageName))
 isDiscussionPage=false;
 }

 if(isLQTPage)
 isDiscussionPage=false;// XXX: for the purpose of section collapsing, that is.
 }

 functionlink(handler,text){
 varspan=document.createElement('span');
 vara=document.createElement('a');
 vartx=document.createTextNode(text);
 a.appendChild(tx);
 a.href='#';
 a.addEventListener('click',function(ev){
 ev.preventDefault();
 ev.stopPropagation();
 returnhandler(ev,a,tx,span);
 },false);
 varlb=document.createElement('span');
 varrb=document.createElement('span');
 lb.textContent='[';lb.className='mw-editsection-bracket';
 rb.textContent=']';rb.className='mw-editsection-bracket';
 span.appendChild(lb);
 span.appendChild(a);
 span.appendChild(rb);
 span.click=function(){
 a.click.apply(a,arguments);
 };
 returnspan;
 }

 vartogglerStore={};
 try{
 togglerStore=JSON.parse(window.localStorage.getItem('kephir-unclutter-togglers'))||{};
 }catch(e){
 /* swallow */
 }

 functiontoggler(element,state,stateKey,showText,hideText){
 showText=showText||'show';
 hideText=hideText||'hide';
 state==stateKeyintogglerStore?togglerStore[stateKey]:state;
 element.style.display=state?'none':'';
 returnlink(function(ev,a,tx){
 state=!state;
 element.style.display=state?'none':'';
 tx.data=state?showText:hideText;
 if(stateKey){
 try{
 togglerStore=JSON.parse(window.localStorage.getItem('kephir-unclutter-togglers'))||{};
 }catch(e){
 /* swallow */
 }
 togglerStore[stateKey]=state;
 try{
 window.localStorage.setItem('kephir-unclutter-togglers',JSON.stringify(togglerStore));
 }catch(e){
 /* swallow */
 }
 }
 returnfalse;
 },state?showText:hideText);
 }

 functionancestors(node){
 varresult=[];
 while(node!==null){
 result[result.length]=node;
 node=node.parentNode;
 }
 returnresult;
 }

 functionclicker(target){
 returnfunction(ev){
 if(ancestors(ev.target).filter(function(item){returnitem.tagName==='A';}).length){
 return;
 }
 target.click();
 };
 }

 functionprocessPreview(){
 vartu=document.getElementsByClassName('templatesUsed')[0],tup,tuul;
 varpt;
 if(tu){
 tup=tu.getElementsByTagName('p')[0];
 tuul=tu.getElementsByTagName('ul')[0];
 }

 varhc=document.getElementsByClassName('hiddencats')[0],hcp,hcul;
 if(hc){
 hcp=hc.getElementsByTagName('p')[0];
 hcul=hc.getElementsByTagName('ul')[0];
 }

 varph=document.getElementById('mw-previewheader');
 if(tup&&tuul){
 tup.appendChild(document.createTextNode(' ('+tuul.getElementsByTagName('li').length+')'));
 tup.appendChild(pt=toggler(tuul,true));
 pt.className='mw-editsection';
 tuul.style.display='none';
 }

 if(hcp&&hcul){
 // hcp.appendChild(document.createTextNode(' (' + hcul.getElementsByTagName('li').length + ')'));
 hcp.appendChild(pt=toggler(hcul,true));
 pt.className='mw-editsection';
 hcul.style.display='none';
 }

 if(ph){
 varpc=document.getElementById('wikiPreview').getElementsByClassName('mw-content-ltr')[0];// XXX
 ph.appendChild(pt=toggler(pc,false));
 pt.className='mw-editsection';
 }

 /* TODO: handle #wikiDiff too */
 }

 if((wgConf.wgAction==='edit')||(wgConf.wgAction==='submit')){
 processPreview();
 if(mw.user.options.get('uselivepreview')=='1'){
 jQuery(mw).bind('LivePreviewDone',processPreview);
 }
 }

 varenarea=document.getElementById('editnotice-area');
 if(((wgConf.wgAction==='submit')||(wgConf.wgAction==='edit'))&&enarea){
 varenn=enarea.getElementsByClassName('editnotice-namespace')[0];
 varnonempty=enn&&enn.textContent.trim();
 vareditintro=document.getElementsByClassName('mw-editintro')[0];
 if(!nonempty){
 varenl=enarea.getElementsByClassName('editnotice-link')[0];
 nonempty=enl&&!enl.classList.contains("editnotice-redlink");
 }

 if(editintro){
 vareiname=mw.util.getParamValue('editintro');

 vareihider=document.createElement('div');
 eihider.className='kephir-unclutter-editintro-hide-link';
 eihider.style.fontSize='smaller';
 eihider.style.textAlign='right';
 eihider.appendChild(toggler(editintro,false,einame?('editintro-'+einame):null,'show editintro','hide editintro'));
 editintro.parentNode.insertBefore(eihider,editintro);
 }

 if(nonempty){
 varhider=document.createElement('div');
 hider.style.fontSize='smaller';
 hider.style.textAlign='right';
 hider.className='kephir-unclutter-editnotice-hide-link';
 hider.appendChild(toggler(enarea,false,'editnotice-'+wgConf.wgPageName,'show editnotices','hide editnotices'));
 enarea.parentNode.insertBefore(hider,enarea);
 }
 }

 if(wgConf.wgAction==='submit'){
 varph=document.getElementById('mw-previewheader');
 if(ph){
 varcont=document.getElementById('wikiPreview').getElementsByClassName('mw-content-ltr')[0];// XXX
 ph.insertBefore(toggler(cont,false),ph.firstChild);
 }
 }

 if(wgConf.wgAction==='view'){
 varcontent=document.getElementById('mw-content-text');
 varallHidden=settings.collapseDiscussionsByDefault;
 varheadlines=document.getElementsByClassName('mw-headline');
 if((headlines.length>1)&&settings.wrapDiscussions&&isDiscussionPage){
 varwrappers={};
 varsect0wrapper=document.createElement('div');
 varl0,l1;
 content.insertBefore(sect0wrapper,content.firstChild);
 while(sect0wrapper.nextSibling){
 if(sect0wrapper.nextSibling.contains(headlines[0]))
 break;
 sect0wrapper.appendChild(sect0wrapper.nextSibling);
 }
 sect0wrapper.className='kephir-unclutter-sectionzero-wrapper';
 document.getElementById('siteSub').appendChild(l0=toggler(sect0wrapper,false,'sect0-'+wgConf.wgPageName,'show header','hide header'));
 document.getElementById('siteSub').appendChild(l1=link(function(ev,a,tx){
 allHidden=!allHidden;
 tx.data=allHidden?'show topics':'hide topics';
 for(varkeyinwrappers){
 if(wrappers[key].wrapper.style.display!==(allHidden?'none':''))
 wrappers[key].click();
 }
 },allHidden?'show topics':'hide topics'));
 l0.className=l1.className='mw-editsection';
 for(vari=0;i<headlines.length;++i){
 varhdr=headlines[i].parentNode;
 varnhdr=null;
 for(varj=i+1;j<headlines.length;++j){
 if(headlines[j].parentNode.tagName===hdr.tagName){
 nhdr=headlines[j].parentNode;
 break;
 }
 }
 varwrapper=document.createElement('div');
 hdr.parentNode.insertBefore(wrapper,hdr.nextSibling);
 while(wrapper.nextSibling){
 if(wrapper.nextSibling.contains(nhdr))
 break;
 wrapper.appendChild(wrapper.nextSibling);
 }
 wrapper.className='kephir-unclutter-'+hdr.tagName+'-contents kephir-unclutter-discussion-contents';
 varheaderLink=toggler(wrapper,(hdr.tagName==='H2')&&settings.collapseDiscussionsByDefault,'header-'+wgConf.wgPageName+'#'+headlines[i].id);
 varsuperwrapper=document.createElement('div');
 hdr.parentNode.insertBefore(superwrapper,hdr);
 superwrapper.appendChild(hdr);
 superwrapper.appendChild(wrapper);
 superwrapper.className='kephir-unclutter-'+hdr.tagName+'-wrapper kephir-unclutter-discussion-wrapper';
 headerLink.className='mw-editsection';
 headerLink.wrapper=wrapper;
 hdr.appendChild(headerLink);
 hdr.style.cursor='pointer';
 hdr.classList.add('kephir-unclutter-collapsible-section');
 hdr.addEventListener('click',clicker(headerLink),false);
 wrappers[headlines[i].id]=headerLink;
 }
 varoldhash=location.hash.substr(1);
 location.hash='';
 window.addEventListener('hashchange',function(ev){
 varid=location.hash.substr(1);
 if(wrappers[id]){
 varh=document.getElementById(id);
 if(wrappers[id].wrapper.style.display==='none'){
 wrappers[id].click();
 window.setTimeout(function(){
 h.scrollIntoView();
 },0);// fix scrolling position
 }
 }
 },false);
 location.hash=oldhash;
 }
 }

 functionescapeClass(clbutt){
 returnclbutt.replace(/[^_a-zA-Z0-9-]/g,function(m){
 /* TODO: do I care or do I not about non-BMP usernames? */
 vart=m.charCodeAt(0).toString(16);
 while(t.length<6)
 t='0'+t;
 return'\\'+t;
 });
 }

 varredirCache={};

 functionsolveRedirect(title){
 if(titleinredirCache)
 returnredirCache[title];
 varapi=newmw.Api();
 varresult=redirCache[title]=title;
 api.ajax({
 action:'query',
 titles:title,
 redirects:'1'
 },{
 async:false,
 success:function(data){
 result=redirCache[title]=data.query.redirects[0].to;
 },
 error:function(){
 thrownewError('redirect resolution failed');
 }
 });
 returnresult;
 }

 functionextractUserName(title){
 varm;

 if((title.getNamespaceId()===wgConf.wgNamespaceIds.user)||(title.getNamespaceId()===wgConf.wgNamespaceIds.user_talk))
 returntitle.getMainText().replace(/\/.*$/,'');
 elseif(title.getNamespaceId()===wgConf.wgNamespaceIds.special)
 if(m=/^(Contributions|EmailUser|Log(?:\/delete|\/protect|\/block|))\/(?![a-z])([^?&#/]+)$/.exec(title.getMainText())){
 if(m[1]==='EmailUser')
 m[2]=m[2].replace(/^User:/i,'');
 returnm[2];
 }else
 returnnull;
 else
 returnnull;
 }

 functionnormaliseUsername(uname){
 vartit;
 try{
 tit=newmw.Title('User:'+uname);
 }catch(e){
 returnnull;
 }
 varnorm=tit.getMainText();
 returnnorm;
 }

 functionunameClasses(username){
 if(mw.util.isIPv4Address(username))
 return'unregistered ipv4';
 if(mw.util.isIPv6Address(username))
 return'unregistered ipv6';
 return'';
 }

 varrxPage=newRegExp('^'+wgConf.wgArticlePath.replace('1ドル','(.*)')+'$');
 functiontargetPage(href,params){
 varuri;
 try{
 uri=newmw.Uri(href);
 }catch(e){
 returnnull;
 }

 if((uri.host!==location.hostname))
 returnnull;
 if(params)
 for(varkinuri.query)
 params[k]=uri.query[k];

 try{
 if(m=rxPage.exec(uri.path))
 returnnewmw.Title(decodeURIComponent(m[1])+(uri.fragment?'#'+uri.fragment:''));// XXX: why does mw.Title not decodeURIComponent on its own?
 elseif(uri.path===wgConf.wgScript)
 returnnewmw.Title(uri.query.title+(uri.fragment?'#'+uri.fragment:''));
 }catch(e){/* failed to parse, bail out. */}

 returnnull;
 }

 functionwrapSignature(node,uname){
 varbadtags=['DIV','DL','DD','BLOCKQUOTE','UL','OL','LI','P','BR','TD','TH','TR','H1','H2','H3','H4','H5','H6','PRE','DEL','INS'];
 varwraptags=['FONT','EM','B','I','SMALL'];
 functionisStylingNode(node,relax){
 if(node.tagName==='FONT')
 returntrue;
 elseif(badtags.indexOf(node.tagName)!==-1)
 returnfalse;
 elseif(['SPAN','SMALL'].indexOf(node.tagName)===-1)
 if((['B','I','EM','STRONG'].indexOf(node.tagName)!==-1)
 &&(node.attributes.length===1)&&node.hasAttribute('style'));
 // do the loop check
 elseif(!relax||(['B','I','EM','STRONG'].indexOf(node.tagName)===-1)
 ||!((node.attributes.length<2)&&((node.attributes.length===1)<=node.hasAttribute('style')))){
 if(node.childNodes){
 varhads=false;
 for(vari=0;i<node.childNodes.length;++i){
 if(node.childNodes[i].nodeType!==document.TEXT_NODE&&!(hads=isStylingNode(node.childNodes[i],true)))
 returnfalse;
 }
 returnhads;
 }
 returnfalse;
 }else;
 elseif(!((node.attributes.length===1)&&node.hasAttribute('style')))
 returnfalse;

 if(node.childNodes){
 for(vari=0;i<node.childNodes.length;++i){
 if(node.childNodes[i].nodeType!==document.TEXT_NODE&&!isStylingNode(node.childNodes[i],true))
 returnfalse;
 }
 }
 returntrue;
 }
 functiongrabProlog(last,wrapper){
 varm;
 while(last.previousSibling){
 if(isStylingNode(last.previousSibling)){
 wrapper.insertBefore(last.previousSibling,wrapper.firstChild);
 continue;
 }

 if((last.previousSibling.nodeType===document.TEXT_NODE)
 &&(m=/[\u2000-\u200a\u2011\x20\x09\xa0\x0a\x0d]*([\u2003\x20\x09\xa0\x0a\x0d][([{]|[‐-][‐-]?|\/?[–—~]\/?|·{1,3}|(?:[\x20\xa0]?[᛭•§|\u2190-\u21ff\u2600-\u27bf\u2200-\u22ff])+|[\u2003\x20\x09\xa0\x0a\x0d])[\u2000-\u200a\u2011\x20\x09\xa0\x0a\x0d]*$/.exec(last.previousSibling.data))){
 last.previousSibling.data=last.previousSibling.data.substr(0,last.previousSibling.data.length-m[0].length);
 wrapper.insertBefore(document.createTextNode(m[0]),wrapper.firstChild);
 if(last.previousSibling.data===''){
 last.parentNode.removeChild(last.previousSibling);
 continue;
 }
 }
 break;
 }
 }
 functioncanBeSigNode(subcheck){
 functioncheckTarget(tit){
 if(tit.namespace===wgConf.wgNamespaceIds.special){
 if(m=/^(Contributions|EmailUser|Log(?:\/delete|\/protect|\/block|))\/(.*)/.exec(tit.getMainText())){
 if(m[1]==='EmailUser')
 m[2]=m[2].replace(/^User:/i,'');
 if(normaliseUsername(m[2])!==uname)
 return0;
 }else
 return-1;
 }elseif((tit.namespace===wgConf.wgNamespaceIds.user)||(tit.namespace===wgConf.wgNamespaceIds.user_talk)){
 if(tit.namespace===wgConf.wgNamespaceIds.user_talk)
 if(sigll[href])
 return-2;// a signature never links to the same page twice.
 if((tit.namespace===wgConf.wgNamespaceIds.user)&&(tit.getMainText().substr(0,uname.length+1)===(uname+'/')))
 return1;
 if(tit.getMainText()!==uname)
 return0;
 sigll[href]=true;
 if(!tit.fragment||/^(no ?bold|top)$/i.test(tit.fragment))
 return1;// OK
 else
 return-3;// invalid!
 }

 if(href.fragment)// section links are probably not parts of a signature.
 return-3;

 return1;
 }
 if(subcheck.nodeType===document.TEXT_NODE)
 returnsubcheck.data.length<64;
 if(subcheck.getElementsByTagName('img').length>0)
 returnnull;// no images are allowed in signatures; reject.
 if(subcheck.getElementsByTagName('li').length>0)
 returnnull;// XXX: I need a better way to do this...
 varsiglinks=Array.prototype.slice.call(subcheck.getElementsByTagName('a'));
 if(subcheck.tagName==='A')
 siglinks.push(subcheck);
 if(wgConf.wgServer==='//en.wikipedia.org'){
 // helps with some false positives
 if(/\b(plainlinks|template-ping)\b/.test(subcheck.className))
 returnnull;
 if(subcheck.querySelector('span.plainlinks'))
 returnnull;
 if(subcheck.querySelector('span.template-ping'))
 returnnull;
 }
 for(vari=0;i<siglinks.length;++i){
 varhref=newmw.Uri(siglinks[i].href);
 varpagepat=newRegExp('^'+wgConf.wgArticlePath.replace(/([\\{}()|.?*+\-\^$\[\]])/g,'\\1ドル').replace('\\1ドル','(.+)')+'$');// XXX: awful
 varm,tit;

 // workaround for [[User:Writ Keeper/Scripts/teahouseTalkbackLink.js]]
 if(window.teahouseTalkbackLink&&/^TBsubmit\d+$/.test(siglinks[i].id))
 continue;

 if(href.host!==wgConf.wgServer.replace(/^\/\//,''))
 returnnull;// reject, external link.

 if(m=pagepat.exec(href.path)){
 tit=newmw.Title(decodeURIComponent(m[1]));
 }elseif(href.path===wgConf.wgScript){
 if(!href.query.title)
 returnnull;
 tit=newmw.Title(href.query.title);
 if(href.query.action&&(['edit','view'].indexOf(href.query.action)===-1))
 returnnull;
 if(href.query.section&&(href.query.section!=='new'))
 returnnull;
 if(Object.keys(href.query).some(function(item){
 return['action','section','redlink','preload','title'].indexOf(item)===-1;
 }))
 returnnull;
 }else
 returnnull;// looks like an external link. there are not allowed, so no signature here.

 if(!tit)
 returnnull;// not a good link.

 if([
 wgConf.wgNamespaceIds.draft,
 wgConf.wgNamespaceIds.draft_talk,
 wgConf.wgNamespaceIds.help,
 wgConf.wgNamespaceIds.help_talk,
 wgConf.wgNamespaceIds.category,
 wgConf.wgNamespaceIds.category_talk,
 wgConf.wgNamespaceIds.file,
 wgConf.wgNamespaceIds.file_talk,
 wgConf.wgNamespaceIds.mediawiki,
 wgConf.wgNamespaceIds.mediawiki_talk,
 wgConf.wgNamespaceIds.template_talk,
 wgConf.wgNamespaceIds.module,
 wgConf.wgNamespaceIds.module_talk,
 ].indexOf(tit.namespace)!==-1)
 returnnull;

 varwhy=checkTarget(tit);
 if(why===0){
 if(siglinks[i].classList.contains('mw-redirect')){
 try{
 tit=newmw.Title(solveRedirect(tit.toString()));
 }catch(e){
 continue;// assume OK
 }
 if(checkTarget(tit)>0)
 continue;
 }
 returnnull;
 }elseif(why<0){
 returnnull;
 }
 }
 returntrue;
 }
 varm;
 varlast=node;
 varwrapper=document.createElement('span');
 // lifted from Comments in Local Time, later relaxed to accommodate a few bloody divas
 vartsregex=/(\s*\d?\d:\d\d(\s+[APap](\. ?)?[Mm](\. ?)?)?,?\s+(\d\d?\s[A-Za-z]+|[A-Za-z]+\s+\d\d?,?)\s+\d\d\d\d|\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d|[A-Za-z]+\s\d\d?,\s\d\d\d\d\s*[;,]\s*\d\d:\d\d)(\s*\(UTC\))?/;
 wrapper.className='kephir-unclutter-signature-wrapper signature signature-'+uname.replace(/ /g,'_')+' '+unameClasses(uname);
 while(last=node,node=node.parentNode){
 vargot=null;
 varsigll={};
 varscnm;

 // XXX: handle {{spa}} and such somehow
 /*if (node.tagName === 'SMALL')
 			return null;*/
 if(badtags.indexOf(last.tagName)!==-1)
 returnnull;

 varsubcheck=last;
 do{
 if(subcheck.classList&&subcheck.classList.contains('before-localcomments')){
 got=subcheck;
 m=[];
 break;
 }elseif(subcheck.getElementsByClassName&&(scnm=subcheck.getElementsByClassName('before-localcomments')).length){
 if(!canBeSigNode(subcheck))
 returnnull;
 scnm=scnm[0];
 varsceit=scnm,scenext=scnm,posnode=subcheck.nextSibling;
 while(sceit!==subcheck.nextSibling){
 while(!scenext.nextSibling){
 scenext=scenext.parentNode;
 if(scenext===subcheck)
 break;
 }
 scenext=scenext.nextSibling;
 subcheck.parentNode.insertBefore(sceit,posnode);
 posnode=sceit.nextSibling;
 sceit=scenext;
 }
 got=subcheck;
 break;
 }elseif((subcheck.nodeType===document.TEXT_NODE)&&(m=tsregex.exec(subcheck.data))){
 // split subcheck into two text nodes: before and after start of match.
 subcheck.parentNode.insertBefore(
 document.createTextNode(subcheck.data.substr(0,m.index)),
 subcheck
 );
 subcheck.data=subcheck.data.substr(m.index);
 if(!canBeSigNode(subcheck.previousSibling))
 returnnull;
 got=subcheck;
 break;
 }elseif(m=tsregex.exec(subcheck.textContent)){
 if(!canBeSigNode(subcheck))
 returnnull;

 // dig up the node
 got=subcheck;
 while(got.nodeType!==document.TEXT_NODE){
 got=got.firstChild;
 while(String(got.textContent).indexOf(m[0])===-1){
 got=got.nextSibling;
 if(!got)
 returnnull;// whoops...
 }
 }

 // split at match
 got.parentNode.insertBefore(
 document.createTextNode(got.data.substr(0,got.data.indexOf(m[0]))),
 got
 );
 got.data=got.data.substr(got.data.indexOf(m[0]));

 // carve it out
 if(got!==subcheck){
 varsceit=got,scenext=got,posnode=subcheck.nextSibling;
 while(sceit){
 while(!scenext.nextSibling){
 scenext=scenext.parentNode;
 if(scenext===subcheck){
 scenext=null;
 break;
 }
 }
 scenext=scenext&&scenext.nextSibling;
 subcheck.parentNode.insertBefore(sceit,posnode);
 posnode=sceit.nextSibling;
 sceit=scenext;
 }
 }
 break;
 }elseif((subcheck.nodeType===document.TEXT_NODE)&&(subcheck.data.length>=64)){
 // long passages of text? probably a false positive.
 returnnull;
 }
 if(!subcheck.getElementsByTagName)
 continue;
 if(!canBeSigNode(subcheck))
 returnnull;
 }while(subcheck=subcheck.nextSibling);

 if(got){
 grabProlog(last,wrapper);
 if(last.parentNode.firstChild===last){
 if(wraptags.indexOf(last.parentNode.tagName)!==-1){
 if(got.nodeType===document.TEXT_NODE){// raw timestamp
 got.parentNode.parentNode.insertBefore(got,got.parentNode.nextSibling);
 last=last.parentNode;
 node=node.parentNode;
 }else{// LocalComments
 varggot=got;
 while(ggot&&!ggot.classList.contains('after-localcomments')){
 ggot=ggot.nextSibling;
 }
 if(!ggot||(ggot.parentNode.lastChild===ggot)){
 varitn=null,lip=got.parentNode.nextSibling;
 for(varit=got;it&&it!==ggot.nextSibling;it=itn){
 itn=it.nextSibling;
 if(lip)
 it.parentNode.parentNode.insertBefore(it,lip);
 else
 it.parentNode.parentNode.appendChild(it);
 lip=it.nextSibling;
 }
 last=last.parentNode;
 node=node.parentNode;
 }
 }
 }
 }
 grabProlog(last,wrapper);
 node.insertBefore(wrapper,last);

 for(varit=last;it&&it!==got;it=wrapper.nextSibling){
 wrapper.appendChild(it);
 }
 if(got.nodeType!==document.TEXT_NODE){
 wrapper.appendChild(got);
 }

 returnwrapper;
 }
 }
 returnnull;
 }

 // XXX: customising colours? remembering across pages?
 varuserColours,userLQTColours;
 varuserColoursQueue={};
 varuserColoursSheet;

 try{
 userColours=JSON.parse(window.sessionStorage.getItem('kephir-unclutter-sigcolours-'+wgConf.wgPageName))||{};
 userLQTColours=JSON.parse(window.sessionStorage.getItem('kephir-unclutter-lqtcolours-'+wgConf.wgPageName))||{};
 }catch(e){
 /* ignore */
 }

 if(settings.signaturesColourise){
 varstyleElm=document.createElement('style');
 styleElm.appendChild(document.createTextNode(''));
 document.head.appendChild(styleElm);
 userColoursSheet=styleElm.sheet||styleElm.styleSheet;
 if(!userColoursSheet){
 settings.signaturesColourise=false;
 }
 if(!userColoursSheet.addRule){
 if(userColoursSheet.insertRule)
 userColoursSheet.addRule=function(selector,css){
 this.insertRule(selector+'{'+css+'}',0);
 };
 else{
 settings.signaturesColourise=false;
 userColoursSheet=null;
 }
 }
 }

 if(userColoursSheet)
 for(varunameinuserColours){
 varcolour=userColours[uname];
 varlqtc=userLQTColours[uname];
 userColoursSheet.addRule(
 '.kephir-unclutter-minisig.signature-'+escapeClass(uname.replace(/ /g,'_')),
 'background: '+colour
 );
 if(settings.liquidThreadsColourPosts&&lqtc){
 userColoursSheet.addRule(
 '.lqt-post-wrapper.post-'+escapeClass(uname.replace(/ /g,'_')),
 'background: '+lqtc
 );
 }
 }

 // this algorithm is described at [[HSL and HSV#Converting to RGB]].
 functionhsv2rgb(hue,sat,val1){
 varchro=val1*sat;
 varval2=val1-chro*Math.abs((hue/120-Math.floor(hue/120))*2-1);
 varval3=val1-chro;

 switch(Math.floor(hue/60)%6){
 case0:return[val1,val2,val3];
 case1:return[val2,val1,val3];
 case2:return[val3,val1,val2];
 case3:return[val3,val2,val1];
 case4:return[val2,val3,val1];
 case5:return[val1,val3,val2];
 }
 }

 functionpickSigColour(){
 // XXX: minimise collisions
 varhue=Math.random()*360;
 varsat=0.9*Math.sqrt(Math.random());
 varval=0.5+Math.pow(Math.random(),1/3)*0.3;

 return{
 lqtVariant:{
 hue:hue,sat:sat/8,val:0.9,
 toString:function(){
 varrgb=hsv2rgb(this.hue,this.sat,this.val);

 return'rgb('+Math.floor(rgb[0]*255)+','+Math.floor(rgb[1]*255)+', '+Math.floor(rgb[2]*255)+')';
 }
 },
 hue:hue,sat:sat,val:val,
 toString:function(){
 varrgb=hsv2rgb(this.hue,this.sat,this.val);

 return'rgba('+Math.floor(rgb[0]*255)+','+Math.floor(rgb[1]*255)+', '+Math.floor(rgb[2]*255)+', 0.175)';
 }
 };
 }

 functionminimiseSig(wrapper,username,annotation){
 functiondisplacement(node){
 varx=0,y=0;
 while(node.offsetParent){
 x+=node.offsetLeft;
 y+=node.offsetTop;
 node=node.offsetParent;
 }
 return[x,y];
 }
 functionel(tag,child,attr,events){
 varnode=document.createElement(tag);

 if(child){
 if(typeofchild!=='object')
 child=[child];
 for(vari=0;i<child.length;++i){
 varch=child[i];
 if((ch===void(null))||(ch===null))
 continue;
 elseif(typeofch!=='object')
 ch=document.createTextNode(String(ch));
 node.appendChild(ch);
 }
 }

 if(attr)for(varkeyinattr){
 node.setAttribute(key,String(attr[key]));
 }

 if(events)for(varkeyinevents){
 node.addEventListener(key,events[key],false);
 }

 returnnode;
 }
 functionlink(child,href,attr,ev){
 attr=attr||{};
 ev=ev||{};
 if(typeofattr==='string'){
 attr={title:attr};
 }
 if(typeofhref==='string')
 attr.href=href;
 else{
 attr.href='javascript:void(null);';
 ev.click=href;
 }
 returnel('a',child,attr,ev);
 }
 functioncwrap(clbutt,child){
 returnel('span',child,{'class':clbutt});
 }
 if(settings.signaturesExceptions.indexOf(username)!==-1)
 return;

 varclbutt='signature-'+username.replace(/ /g,'_');
 varminisig=el('span',[
 el('span',['—'],{'class':'dash'}),
 '\xa0',
 mw.util.isIPv4Address(username)||mw.util.isIPv6Address(username)
 ?el('span',[username],{'class':'username'})
 :link([username],mw.util.getUrl('User:'+username),{'class':'username'}),
 annotation?el('span',[
 ' ('+annotation+')'
 ],{"class":"annotation"}):void(null),
 ' ',
 el('small',[
 '(',
 cwrap('tlk-link',[link(['talk'],mw.util.getUrl('User talk:'+username),
 'Discussion page of this user'
 )]),
 cwrap('ctb-link',['\xa0•\xa0',link(['contrib'],mw.util.getUrl('Special:Contributions/'+username),
 'Contributions of this user'
 )]),
 cwrap('act-link',['\xa0•\xa0',link(['actions'],mw.util.getUrl('Special:Log',{user:username}),
 'Actions performed by this user'
 )]),
 cwrap('log-link',['\xa0•\xa0',link(['log'],mw.util.getUrl('Special:Log',{page:'User:'+username}),
 'Actions performed on this user'
 )]),
 cwrap('sig-link',['\xa0•\xa0',link(['sig'],function(ev){
 wrapper.style.display=wrapper.style.display==='none'?'inline-block':'none';
 if(wrapper.style.display!=='none'){
 varmsd=displacement(minisig);
 varwsd=displacement(wrapper.offsetParent);
 wrapper.style.top=(msd[1]-wsd[1]+minisig.offsetHeight+4)+'px';
 wrapper.style.left=(msd[0]-wsd[0])+'px';
 wrapper.style.position='absolute !important';
 }
 },'Show original signature')]),
 ')'
 ]),
 ],{'class':'kephir-unclutter-minisig signature '+clbutt+' '+unameClasses(username)});

 wrapper.style.cssText+='; position: absolute !important; z-index: 69;';
 wrapper.style.display='none';
 wrapper.parentNode.insertBefore(document.createTextNode(' '),wrapper);
 wrapper.parentNode.insertBefore(minisig,wrapper);
 wrapper.parentNode.insertBefore(document.createTextNode(' '),wrapper);
 minisig.insertBefore(wrapper,minisig.firstChild);
 wrapper.style.background='#ffffcc';
 wrapper.style.border='1px solid black';
 wrapper.style.padding='0.2em';

 returnminisig;
 }

 functionprocessLiquidSignature(lqtwrapper){
 // determine username
 varsiglinks=lqtwrapper.getElementsByTagName('a');
 varusername,oldname,tparams={};

 // the checks are much lighter here, since we are much more sure that this is a signature
 for(vark=0;k<siglinks.length;++k){
 vartitle=targetPage(siglinks[k].href,tparams);
 if(!title)
 continue;

 varoldname=(username=extractUserName(title));
 if(!oldname)
 continue;// XXX

 if(siglinks[k].classList.contains('mw-redirect')){
 try{
 username=extractUserName(newmw.Title(solveRedirect(title.toString())))||oldname;
 }catch(e){}
 }
 break;
 }

 if(!username)
 return;// skip. what else can we do?

 varwrapper=document.createElement('span');
 lqtwrapper.insertBefore(wrapper,lqtwrapper.firstChild);
 while(wrapper.nextSibling)
 wrapper.appendChild(wrapper.nextSibling);

 varcontext={
 sigOriginal:wrapper,
 oldUsername:oldname,
 username:username,
 annotation:settings.userAnnotations[username],
 colourise:settings.signaturesColourise,
 colour:userColours[username]||(userColoursQueue[username]?userColoursQueue[username].colour:void(0)),
 lqtWrapper:lqtwrapper,
 lqtTimestamp:lqtwrapper.nextSibling,
 };

 while(lqtwrapper=lqtwrapper.parentNode)
 if(lqtwrapper.classList.contains('lqt-post-wrapper'))
 break;
 context.lqtPostWrapper=lqtwrapper;
 lqtwrapper.classList.add('post-'+username.replace(/ /g,'_'));

 if(settings.processSig(context)!==true){
 if(!context.annotation&&(oldname!==username))
 context.annotation=oldname;
 context.sigMinimised=minimiseSig(wrapper,username,context.annotation);
 }
 settings.postProcessSig(context);
 if(context.colourise&&!userColours[username]){
 varuq=userColoursQueue[username]=userColoursQueue[username]||{count:0};
 uq.colour=context.colour;
 uq.count++;
 }
 }

 functionassignColours(){
 if(!userColoursSheet)
 return;

 varqueue=Object.keys(userColoursQueue).sort(function(apple,orange){
 if(userColoursQueue[apple].colour&&!userColoursQueue[orange].count)
 return-1;
 elseif(!userColoursQueue[apple].colour&&userColoursQueue[orange].count)
 return1;
 returnuserColoursQueue[apple].count-userColoursQueue[orange].count;
 });

 for(varj=0;j<queue.length;++j){
 varcolour=(userColoursQueue[queue[j]].colour||pickSigColour());
 userColours[queue[j]]=String(colour);
 userLQTColours[queue[j]]=String(colour.lqtVariant||colour);
 userColoursSheet.addRule(
 '.kephir-unclutter-minisig.signature-'+escapeClass(queue[j].replace(/ /g,'_')),
 'background: '+colour
 );
 if(settings.liquidThreadsColourPosts){
 userColoursSheet.addRule(
 '.lqt-post-wrapper.post-'+escapeClass(queue[j].replace(/ /g,'_')),
 'background: '+colour.lqtVariant||colour
 );
 }
 }

 userColoursQueue={};

 try{
 if(!Object.keys(userColours).length)
 return;
 window.sessionStorage.setItem('kephir-unclutter-sigcolours-'+wgConf.wgPageName,JSON.stringify(userColours));
 window.sessionStorage.setItem('kephir-unclutter-lqtcolours-'+wgConf.wgPageName,JSON.stringify(userLQTColours));
 }catch(e){
 /* ignore */
 }
 }

 if(((wgConf.wgNamespaceNumber>0)||(wgConf.wgCanonicalSpecialPageName==='NewMessages'))&&(wgConf.wgAction==='view')&&settings.signaturesProcess){
 if(isLQTPage){/* lovely. */
 mw.loader.using(['ext.liquidThreads'],function(){
 varsigs=document.getElementsByClassName('lqt-thread-user-signature');
 for(varj=0;j<sigs.length;++j){
 processLiquidSignature(sigs[j]);
 }

 var_setupThread=window.liquidThreads.setupThread;
 window.liquidThreads.setupThread=function(container){
 varresult=_setupThread.apply(this,arguments);
 varsigs=container[0].getElementsByClassName('lqt-thread-user-signature');
 for(varj=0;j<sigs.length;++j){
 processLiquidSignature(sigs[j]);
 }
 assignColours();
 returnresult;
 };

 assignColours();
 });

 return;
 }

 varlinks=(document.getElementById('mw-content-text')||{getElementsByTagName:function(){return[];}}).getElementsByTagName('a');
 for(vari=0;i<links.length;++i){
 varm;
 if(links[i].processedSig)
 continue;

 vartparams={};
 vartitle=targetPage(links[i].href,tparams);
 if(!title)
 continue;
 varoldname;

 if(tparams.redlink?tparams.action!=='edit':tparams.action)
 continue;

 if((title.getNamespaceId()===wgConf.wgNamespaceIds.user)||(title.getNamespaceId()===wgConf.wgNamespaceIds.user_talk))
 if(title.fragment&&!/^(top|no ?bold)$/i.test(title.fragment))
 continue;
 elseif(title.getPrefixedDb().indexOf('/')!==-1)
 continue;

 if(!(oldname=extractUserName(title)))
 continue;

 varusername=oldname;
 if(links[i].classList.contains('mw-redirect')){
 try{
 username=extractUserName(newmw.Title(solveRedirect(title.toString())))||oldname;
 }catch(e){}
 }
 varwrapper=wrapSignature(links[i],username);
 if(wrapper){
 varsiglinks=wrapper.getElementsByTagName('a');
 varminisig=null;
 for(varj=0;j<siglinks.length;++j)
 siglinks[j].processedSig=true;

 varcontext={
 sigOriginal:wrapper,
 oldUsername:oldname,
 username:username,
 annotation:settings.userAnnotations[username],
 colourise:settings.signaturesColourise,
 colour:userColours[username]||(userColoursQueue[username]?userColoursQueue[username].colour:void(0))
 };
 if(settings.processSig(context)!==true){
 if(!context.annotation&&(oldname!==username))
 context.annotation=oldname;
 context.sigMinimised=minimiseSig(wrapper,username,context.annotation,context.colourise?context.colour:null);
 }
 settings.postProcessSig(context);
 if(context.colourise&&!userColours[username]){
 varuq=userColoursQueue[username]=userColoursQueue[username]||{count:0};
 uq.colour=context.colour;
 uq.count++;
 }

 if(minisig){
 varsiglinks=minisig.getElementsByTagName('a');
 for(varj=0;j<siglinks.length;++j)
 siglinks[j].processedSig=true;
 }
 }
 }
 assignColours();
 }

 });

AltStyle によって変換されたページ (->オリジナル) /