2024-09-15 17:44:53 +00:00
document . addEventListener ( 'DOMContentLoaded' , function ( ) {
loading ( )
2024-10-06 15:20:32 +00:00
var hold , external , timeout , ac , last , darklight = document . getElementById ( 'darkcss' ) . getAttribute ( 'href' )
2024-09-15 17:44:53 +00:00
document . getElementById ( 'instance' ) . addEventListener ( 'keydown' , function ( event ) {
2024-10-14 23:09:37 +00:00
if ( event . key && ! event . ctrlKey && ! event . altKey ) {
2024-09-21 20:44:41 +00:00
if ( ( event . key . length === 1 && /[a-z0-9.\-*:]/i . test ( event . key ) ) || ( event . key === 'Backspace' && event . target . value !== '' ) ) {
last = event . target . value
} else {
event . preventDefault ( )
event . stopPropagation ( )
}
2024-09-15 17:44:53 +00:00
} else {
event . preventDefault ( )
event . stopPropagation ( )
}
} )
document . getElementById ( 'instance' ) . addEventListener ( 'keyup' , function ( event ) {
2024-10-14 23:09:37 +00:00
if ( event . key && ! event . ctrlKey && ! event . altKey ) {
2024-09-21 20:44:41 +00:00
if ( ( event . key . length === 1 && /[a-z0-9.\-*:]/i . test ( event . key ) ) || ( event . key === 'Backspace' && event . target . value !== '' ) ) {
2024-09-22 23:48:53 +00:00
keypress ( event . target . value )
2024-10-14 23:09:37 +00:00
} else if ( event . target . value === '' && document . getElementById ( 'instancelist' ) . firstChild ? . innerText !== 'Top 100' ) {
ranking ( )
2024-09-21 20:44:41 +00:00
} else {
event . preventDefault ( )
event . stopPropagation ( )
}
2024-09-15 17:44:53 +00:00
} else {
event . preventDefault ( )
event . stopPropagation ( )
}
} )
var modal = document . getElementById ( 'modal' ) ,
closemodal = document . getElementById ( 'closemodal' ) ,
modalcontent = document . querySelector ( '.modal-content' )
document . getElementById ( 'reverse' ) . addEventListener ( 'click' , function ( event ) {
var content = document . getElementById ( 'instance' ) . value
if ( content && content . length > 0 ) {
loading ( )
fetch ( '/api/block_count/' + content ) . then ( async function ( result ) {
2024-11-19 01:17:17 +00:00
var res = await result . text ( ) || ''
2024-11-19 01:56:23 +00:00
if ( res . length > 0 ) {
2024-11-15 20:56:24 +00:00
document . getElementById ( 'blockcount' ) . innerText = res . split ( '\n' ) . length
2024-09-15 17:44:53 +00:00
document . getElementById ( 'blockinstance' ) . innerText = 'ing ' + content
2024-10-13 23:54:16 +00:00
document . getElementById ( 'blocktook' ) . innerText = ''
2024-09-15 17:44:53 +00:00
var list = document . getElementById ( 'blocklist' ) ,
download = document . getElementById ( 'download' )
download . removeAttribute ( 'href' )
download . removeAttribute ( 'download' )
download . style . display = 'none'
while ( list . hasChildNodes ( ) ) {
list . removeChild ( list . firstChild )
}
2024-11-15 20:56:24 +00:00
res . split ( '\n' ) . map ( JSON . parse ) . map ( function ( instance , index ) {
2024-09-15 17:44:53 +00:00
var li = document . createElement ( 'li' ) ,
text = document . createTextNode ( ( index + 1 ) + '. ' ) ,
link = '<a href="/' + ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ? '?matrix' : '' ) + '#' + instance . instance + '" onclick="window.location.href=this.href; window.location.reload(false);">' + instance . instance + '</a>' ,
text2 = document . createTextNode ( instance . comment ? ' - ' + instance . comment : '' )
li . appendChild ( text )
li . insertAdjacentHTML ( 'beforeend' , link )
li . appendChild ( text2 )
blocklist . appendChild ( li )
} )
listinstance ( content , new AbortController ( ) )
modalcontent . style . animationName = 'animatetop'
modal . style . display = 'block'
var locationsearch = ! new URLSearchParams ( window . location . search ) . has ( 'reverse' ) ? window . location . search ? window . location . search + '&reverse' : '?reverse' : window . location . search
history . pushState ( { } , null , '/' + locationsearch + '#' + content )
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
var walker = document . createTreeWalker ( list , NodeFilter . SHOW _TEXT )
while ( walker . nextNode ( ) ) {
if ( walker . currentNode . textContent . length > 1 ) {
new Messenger ( walker . currentNode )
}
}
}
document . getElementById ( 'loader-content' ) . style . display = 'none'
}
} )
}
} )
document . body . addEventListener ( 'click' , function ( event ) {
if ( event . target == modal ) {
modalcontent . style . animationName = 'animatebottom'
}
} )
closemodal . addEventListener ( 'click' , function ( event ) {
modalcontent . style . animationName = 'animatebottom'
} )
modalcontent . addEventListener ( 'animationend' , function ( event ) {
if ( event . animationName === 'animatebottom' ) {
modal . style . display = 'none'
}
} )
document . getElementById ( 'title' ) . addEventListener ( 'click' , function ( event ) {
document . getElementById ( 'instance' ) . value = ''
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
window . location . href = '/?matrix'
} else {
window . location . href = '/'
}
event . preventDefault ( )
event . stopPropagation ( )
} )
document . getElementById ( 'capture' ) . addEventListener ( 'click' , function ( event ) {
html2canvas ( document . querySelector ( '.modal-body' ) ) . then ( function ( canvas ) {
var a = document . createElement ( 'a' )
a . download = 'fediblock-' + Date . now ( ) + '.png'
a . href = canvas . toDataURL ( { type : 'image/png' } )
a . type = 'image/png'
a . target = '_blank'
a . dispatchEvent ( new MouseEvent ( 'click' ) )
} )
} )
2024-09-23 00:16:39 +00:00
document . getElementById ( 'download_index' ) . addEventListener ( 'click' , function ( event ) {
2024-09-22 23:22:27 +00:00
loading ( )
ac = new AbortController ( )
2024-09-23 00:20:45 +00:00
fetch ( '/api/download_index' , { signal : ac . signal } ) . then ( async function ( result ) {
2024-09-22 23:48:53 +00:00
var res = await result . blob ( ) ,
a = document . createElement ( 'a' )
2024-10-13 22:05:40 +00:00
a . download = 'fediblock-index.jsonl.gz'
2024-09-23 00:49:15 +00:00
a . href = URL . createObjectURL ( res )
2024-09-23 22:15:05 +00:00
a . type = 'application/gzip'
2024-09-22 23:48:53 +00:00
a . target = '_blank'
a . dispatchEvent ( new MouseEvent ( 'click' ) )
2024-09-22 23:22:27 +00:00
document . getElementById ( 'loader-content' ) . style . display = 'none'
2024-09-22 23:48:53 +00:00
} ) . catch ( function ( err ) {
console . error ( err )
document . getElementById ( 'loader-content' ) . style . display = 'none'
} )
event . preventDefault ( )
event . stopPropagation ( )
2024-09-22 23:22:27 +00:00
} )
2024-10-06 15:20:32 +00:00
document . getElementById ( 'darklight' ) . addEventListener ( 'click' , function ( event ) {
if ( event . target . innerText === '☼' ) {
document . getElementById ( 'darkcss' ) . setAttribute ( 'href' , '' )
2024-10-05 23:47:07 +00:00
event . target . innerText = '☽'
} else {
2024-10-06 15:20:32 +00:00
document . getElementById ( 'darkcss' ) . setAttribute ( 'href' , darklight )
2024-10-05 23:47:07 +00:00
event . target . innerText = '☼'
}
} )
2024-09-22 23:48:53 +00:00
function keypress ( content ) {
2024-09-15 17:44:53 +00:00
loading ( )
if ( timeout ) {
clearTimeout ( timeout )
}
if ( ac && ac . signal ) {
ac . abort ( )
}
ac = new AbortController ( )
if ( content . length === 0 ) {
hold = true
ranking ( )
} else if ( content . length > 0 && ! hold ) {
hold = true
listinstance ( content , ac )
} else if ( content . length > 0 && hold ) {
2024-09-21 20:23:39 +00:00
timeout = setTimeout ( function ( ) {
2024-09-15 17:44:53 +00:00
listinstance ( content , ac )
} , 300 )
}
}
function listinstance ( content , ac ) {
loading ( )
var list = document . getElementById ( 'instancelist' )
fetch ( '/api/list/' + content , { signal : ac . signal } ) . then ( async function ( result ) {
var res = await result . json ( )
if ( res && Array . isArray ( res . instances ) && Array . isArray ( res . suggests ) ) {
while ( list . hasChildNodes ( ) ) {
list . removeChild ( list . firstChild )
}
2024-09-21 20:23:39 +00:00
res . instances . map ( function ( r ) {
2024-09-15 17:44:53 +00:00
var li = document . createElement ( 'li' )
li . innerHTML = r . domain + ( r . blocks ? ' - ' + r . blocks + ' blocks' : '' )
+ ( r . nodeinfo ? ' <a href="/api/detail_nodeinfo/' + r . domain + '" title="Nodeinfo for ' + r . domain + '" target="_blank">ⓘ</a>' : '' )
2024-11-19 01:56:23 +00:00
+ ( r . last ? '<br /><br />' + 'Last update: ' + ( new Date ( r . last ) ) . toLocaleString ( ) : '' )
2024-11-19 01:17:17 +00:00
+ ( r . api ? . title ? '<br /><br />' + r . api . title + ' - ' + r . api . uri + '<br />'
2024-09-15 17:44:53 +00:00
+ ( r . api . email ? 'Email: ' + r . api . email + '<br />' : '' )
+ 'Registration: ' + ( r . api . registrations ? 'open' : 'closed' ) + ' - Version: ' + r . api . version + '<br />'
+ ( r . api . stats ? 'Users: ' + r . api . stats . user _count + ' - Statuses: ' + r . api . stats . status _count + ' - Domains: ' + r . api . stats . domain _count + '<br />' : '' )
+ ( r . api . description ? 'Description: ' + r . api . description + '<br />' : '' )
+ ( r . api . thumbnail ? '<img domain="' + r . domain + '" loading="lazy" src="' + r . api . thumbnail + '" /><br />' : '' ) : '' )
li . setAttribute ( 'data-domain' , r . domain )
li . addEventListener ( 'click' , function ( event ) {
if ( event . target . matches ( 'a' ) ) {
return true
}
loading ( )
var blocklist = document . getElementById ( 'blocklist' ) ,
download = document . getElementById ( 'download' ) ,
domain = event . target . getAttribute ( 'data-domain' )
while ( blocklist . hasChildNodes ( ) ) {
blocklist . removeChild ( blocklist . firstChild )
}
fetch ( '/api/detail/' + domain ) . then ( async function ( result ) {
var res = await result . json ( )
if ( res . blocks && Array . isArray ( res . blocks ) && res . blocks . length > 0 ) {
var csv = '#domain,#severity,#reject_media,#reject_reports,#public_comment,#obfuscate\n'
2024-09-21 20:23:39 +00:00
res . blocks . map ( function ( r , i ) {
2024-09-15 17:44:53 +00:00
var liblock = document . createElement ( 'li' ) ,
text = document . createTextNode ( ( i + 1 ) + '. ' ) ,
link = '<a href="/' + ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ? '?matrix' : '' ) + '#' + r . domain + '" onclick="window.location.href=this.href; window.location.reload(false);">' + r . domain + '</a>' ,
textSeverity = document . createTextNode ( r . severity ? ' - ' + r . severity : '' ) ,
textComment = document . createTextNode ( r . comment ? ' - ' + r . comment : '' )
liblock . appendChild ( text )
liblock . insertAdjacentHTML ( 'beforeend' , link )
liblock . appendChild ( textSeverity )
liblock . appendChild ( textComment )
blocklist . appendChild ( liblock )
csv += ! r . domain . match ( /\*/ ) ? r . domain + ',' + ( r . severity ? r . severity : '' ) + ',False,False,' + ( r . comment ? '"' + r . comment + '"' : '' ) + ',False\n' : ''
} )
modalcontent . style . animationName = 'animatetop'
modal . style . display = 'block'
document . getElementById ( 'blockcount' ) . innerText = res . blocks . length
document . getElementById ( 'blockinstance' ) . innerHTML = 'ed by ' + ( res . api ? '<a href="/api/detail_api/' + res . instance + '" title="API info for ' + res . instance + '" target="_blank">'
+ res . instance + '</a>' : res . instance ) + ( res . nodeinfo ? ' <a href="/api/detail_nodeinfo/' + res . instance + '" title="Nodeinfo for ' + res . instance + '" target="_blank">ⓘ</a>' : '' )
+ '<br/>Last update: ' + ( new Date ( res . last ) ) . toLocaleString ( )
2024-10-13 22:05:40 +00:00
document . getElementById ( 'blocktook' ) . innerText = '(search in ' + res . took + 'ms)'
2024-09-15 17:44:53 +00:00
if ( csv . split ( '\n' ) . length > 2 ) {
download . href = window . URL . createObjectURL ( new Blob ( [ csv ] , { type : 'text/csv' } ) )
download . download = 'fediblock-' + res . instance + '.csv'
download . style . display = 'inherit'
} else {
download . removeAttribute ( 'href' )
download . removeAttribute ( 'download' )
download . style . display = 'none'
}
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
var walker = document . createTreeWalker ( blocklist , NodeFilter . SHOW _TEXT )
while ( walker . nextNode ( ) ) {
if ( walker . currentNode . textContent . length > 1 ) {
new Messenger ( walker . currentNode )
}
}
}
} else {
var a = document . createElement ( 'a' )
a . href = '/api/detail_api/' + domain
a . title = 'API info for ' + domain
a . target = '_blank'
a . dispatchEvent ( new MouseEvent ( 'click' ) )
}
document . getElementById ( 'loader-content' ) . style . display = 'none'
} )
window . location . hash = domain
document . getElementById ( 'loader-content' ) . style . display = 'none'
} )
list . appendChild ( li )
} )
var placeholder = document . getElementById ( 'placeholder' )
if ( res . suggests . length > 0 ) {
2024-09-21 20:23:39 +00:00
placeholder . innerHTML = res . suggests . map ( function ( instance ) {
return '<a href="/' + ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ? '?matrix' : '' ) + '#' + instance + '" onclick="suggest(this.innerText);">' + instance + '</a>'
} ) . join ( ', ' )
2024-09-15 17:44:53 +00:00
} else {
placeholder . innerText = ''
}
if ( external ) {
document . getElementById ( 'instancelist' ) . childNodes . forEach ( function ( node ) {
if ( node . textContent . split ( ' ' ) [ 0 ] . trim ( ) === content ) {
node . dispatchEvent ( new MouseEvent ( 'click' ) )
}
} )
external = false
}
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
var walker = document . createTreeWalker ( list , NodeFilter . SHOW _TEXT )
while ( walker . nextNode ( ) ) {
if ( walker . currentNode . textContent . length > 1 ) {
new Messenger ( walker . currentNode )
}
}
}
}
document . getElementById ( 'loader-content' ) . style . display = 'none'
hold = false
2024-09-21 20:23:39 +00:00
} ) . catch ( function ( err ) {
2024-09-15 17:44:53 +00:00
// console.error(err)
document . getElementById ( 'loader-content' ) . style . display = 'none'
hold = false
} )
}
function ranking ( ) {
loading ( )
var list = document . getElementById ( 'instancelist' ) ,
placeholder = document . getElementById ( 'placeholder' )
fetch ( '/api/ranking' ) . then ( async function ( result ) {
var res = await result . json ( )
if ( Array . isArray ( res ) && res . length > 0 ) {
while ( list . hasChildNodes ( ) ) {
list . removeChild ( list . firstChild )
}
var li = document . createElement ( 'li' ) ,
strong = document . createElement ( 'strong' ) ,
text = document . createTextNode ( 'Top 100' )
strong . appendChild ( text )
li . appendChild ( strong )
list . appendChild ( li )
2024-09-21 20:23:39 +00:00
res . map ( function ( r , i ) {
2024-09-15 17:44:53 +00:00
var li = document . createElement ( 'li' ) ,
text = document . createTextNode ( ` ${ i + 1 } - ${ r . domain } - ${ r . count } blocks ` )
li . addEventListener ( 'click' , function ( event ) {
var instance = document . getElementById ( 'instance' ) ,
text = event . target . innerText . split ( ' - ' ) [ 1 ] . trim ( )
instance . value = text
document . getElementById ( 'reverse' ) . click ( )
} )
li . appendChild ( text )
list . appendChild ( li )
} )
}
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
var walker = document . createTreeWalker ( list , NodeFilter . SHOW _TEXT )
while ( walker . nextNode ( ) ) {
if ( walker . currentNode . textContent . length > 1 ) {
new Messenger ( walker . currentNode )
}
}
}
placeholder . innerText = ''
hold = false
document . getElementById ( 'loader-content' ) . style . display = 'none'
2024-09-21 20:23:39 +00:00
} ) . catch ( function ( err ) {
2024-09-15 17:44:53 +00:00
console . error ( err )
hold = false
document . getElementById ( 'loader-content' ) . style . display = 'none'
} )
}
function suggest ( urlitem ) {
var instance = document . getElementById ( 'instance' )
window . location . hash = urlitem
instance . value = urlitem
listinstance ( urlitem , new AbortController ( ) )
}
function loading ( ) {
var loader = document . getElementById ( 'load' ) ,
loaders = [ 'loader-pong' , 'loader-pacman' , 'loader-abyss' , 'loader-jump' , 'loader-loading' , 'loader-avenger' , 'loader-mario' ]
if ( loader . classList . value ) {
loader . classList . remove ( loader . classList . value )
}
loader . classList . add ( loaders [ Math . floor ( Math . random ( ) * loaders . length ) ] )
document . getElementById ( 'loader-content' ) . style . display = 'initial'
}
window . suggest = suggest
fetch ( '/api/count' ) . then ( async function ( result ) {
var res = await result . json ( )
if ( res && res . count ) {
fetch ( '/api/stats' ) . then ( async function ( statsresult ) {
var statsres = await statsresult . json ( )
if ( statsres ) {
document . getElementById ( 'count' ) . innerHTML = res . count + '<div id="tooltip">' +
'<u><strong><center>STATS</center></strong></u>' +
'<ul><li>Statuses AVG: ' + Math . round ( statsres . status _avg ) + '</li>' +
'<li>Statuses MAX: ' + statsres . status _max + '</li>' +
'<li>Domain AVG: ' + Math . round ( statsres . domain _avg ) + '</li>' +
'<li>Domain MAX: ' + statsres . domain _max + '</li>' +
'<li>Users AVG: ' + Math . round ( statsres . user _avg ) + '</li>' +
'<li>Users MAX: ' + statsres . user _max + '</li>' +
'<li>Stats Instances: ' + statsres . stats _filtered + '</li>' +
'<li>Total Instances: ' + statsres . instance _count + '</li>' +
'<li>Users by Instance: ' + ( Math . round ( statsres . user _avg ) / statsres . instance _count ) . toFixed ( 2 ) + '</li>' +
'<li>Statuses by Domain: ' + ( Math . round ( statsres . status _avg ) / Math . round ( statsres . domain _avg ) ) . toFixed ( 2 ) + '</li>' +
'<li>Statuses by User: ' + ( Math . round ( statsres . status _avg ) / Math . round ( statsres . user _avg ) ) . toFixed ( 2 ) + '</li>' +
'</ul></div>'
} else {
document . getElementById ( 'count' ) . innerText = res . count
}
} )
fetch ( '/api/outbox' ) . then ( async function ( result ) {
var res = await result . json ( )
if ( res && res . length > 0 ) {
var bounce = document . getElementById ( 'bounce' ) ,
2024-10-06 16:12:47 +00:00
host = new URL ( window . location . href ) . host ,
reg = '(<\/?p>|(https?:\/\/)?' + host + ')'
2024-09-21 20:23:39 +00:00
bounce . innerHTML = res . map ( function ( p ) { return ` ${ p . content . replace ( new RegExp ( reg , 'igm' ) , '' ) } ${ dayjs ( ) . to ( p . published ) } ` } ) . join ( ' | ' )
2024-09-15 17:44:53 +00:00
}
} )
fetch ( '/api/served' ) . then ( async function ( result ) {
var res = await result . json ( )
if ( res . served ) {
var served = document . getElementById ( 'served' )
served . innerText = res . served
}
if ( res . lastscan ) {
var lastscan = document . getElementById ( 'lastscan' )
lastscan . innerText = res . lastscan
}
if ( res . server ) {
var server = document . getElementById ( 'server' )
server . innerHTML = '<a href="/' + ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ? '?matrix' : '' ) + '#' + res . server + '" onclick="window.location.href=this.href; window.location.reload(false);">' + res . server + '</a>'
}
if ( res . instances ) {
var instances = document . getElementById ( 'instances' )
instances . innerText = res . instances
}
if ( res . peers ) {
var peers = document . getElementById ( 'peers' )
peers . innerText = res . peers
}
if ( res . created ) {
var created = document . getElementById ( 'created' )
created . innerText = res . created
}
if ( res . updated ) {
var updated = document . getElementById ( 'updated' )
updated . innerText = res . updated
}
} )
}
} )
if ( window . location . hash && window . location . hash !== null && window . location . hash !== '#' ) {
var instance = document . getElementById ( 'instance' ) ,
urlitem = window . location . hash . substring ( 1 )
instance . value = urlitem
if ( new URLSearchParams ( window . location . search ) . has ( 'reverse' ) ) {
document . getElementById ( 'reverse' ) . click ( )
} else {
external = true
listinstance ( urlitem , new AbortController ( ) )
}
} else {
ranking ( )
document . getElementById ( 'instance' ) . focus ( )
}
var source = new window . EventSource ( '/api/scan' ) ,
scan = document . getElementById ( 'scan' )
source . onmessage = function ( event ) {
if ( event . data ) {
if ( event . data . length > 0 ) {
scan . innerText = 'Async Scanning' + event . data
} else {
scan . innerText = 'Async Scanning...'
}
}
}
source . onerror = function ( error ) {
console . error ( error )
}
if ( new URLSearchParams ( window . location . search ) . has ( 'matrix' ) ) {
var walker = document . createTreeWalker ( document , NodeFilter . SHOW _TEXT )
while ( walker . nextNode ( ) ) {
if ( walker . currentNode . textContent . length > 1 ) {
new Messenger ( walker . currentNode )
}
}
var matrix = document . getElementById ( 'matrix' )
matrix . href = '/'
2024-09-22 01:01:51 +00:00
matrix . innerText = 'on'
2024-09-15 17:44:53 +00:00
} else {
var matrix = document . getElementById ( 'matrix' )
matrix . href = '/?matrix'
2024-09-22 01:01:51 +00:00
matrix . innerText = 'off'
2024-09-15 17:44:53 +00:00
}
} )