Add comments
This commit is contained in:
2 files changed
+29
-1
No files matched your search
@@ -1 +1 @@
|
||||
{"version":3,"sources":["imagesloaded.pkgd.min.js","photoswipe-ui-default.min.js","photoswipe.min.js","prism.js","dropdown.js","lightbox.js","purify.min.js","reframe.min.js","casper.js","mastodon.js","pagination.js","theme.js"],"names":["e","t","define","amd","module","exports","EvEmitter","window","this","prototype","on","n","i","_events","indexOf","push","once","_onceEvents","off","length","splice","emitEvent","slice","o","r","apply","allOff","require","imagesLoaded","s","document","querySelectorAll","elements","Array","isArray","d","call","options","getImages","h","jqDeferred","Deferred","setTimeout","check","bind","a","error","img","url","element","Image","jQuery","console","u","Object","create","images","forEach","addElementImages","nodeName","addImage","background","addElementBackgroundImages","nodeType","1","9","11","getComputedStyle","exec","backgroundImage","addBackground","progress","progressedCount","hasAnyBroken","complete","isLoaded","notify","debug","log","isComplete","getIsImageComplete","confirm","naturalWidth","proxyImage","addEventListener","src","handleEvent","type","onload","unbindEvents","onerror","removeEventListener","makeJQueryPlugin","fn","promise","b","PhotoSwipeUI_Default","A","event","q","timeToIdle","mouseUsed","k","K","c","f","target","srcElement","getAttribute","g","S","onTap","name","stopPropagation","features","isOldAndroid","D","getNumItemsFn","p","C","E","y","F","removeClass","addClass","H","shareButtons","getImageURLForShare","getPageURLForShare","getTextForShare","replace","encodeURIComponent","id","download","label","parseShareButtonOut","children","innerHTML","onclick","G","I","closeElClasses","hasClass","clearTimeout","J","v","setIdle","L","relatedTarget","toElement","timeToIdleOutside","O","m","P","vGap","likelyTouchDevice","screen","width","fitControlsWidth","barsSize","captionEl","bottom","createEl","appendChild","insertBefore","addCaptionHTMLFn","clientHeight","parseInt","top","T","className","option","onInit","getChildByClass","j","l","w","x","z","loadingIndicatorDelay","title","closeEl","fullscreenEl","zoomEl","shareEl","counterEl","arrowEl","preloaderEl","tapToClose","tapToToggleControls","clickToCloseNonZoomable","currItem","location","href","indexIndicatorSep","shout","hasAttribute","open","Math","round","toggleDesktopZoom","close","prev","next","isFullscreen","exit","enter","init","extend","scrollWrap","listen","hideControls","showControls","update","initialZoomLevel","getZoomLevel","zoomTo","getDoubleTapZoom","test","tagName","prevent","onGlobalTap","onMouseOver","clearInterval","unbind","eventK","updateFullscreen","hideAnimationDuration","removeChild","showAnimationDuration","setInterval","getFullscreenAPI","template","loading","allowProgressiveImg","updateIndexIndicator","setScrollOffset","getScrollY","getCurrentIndex","detail","pointerType","fitRatio","releasePoint","supportsFullscreen","exitFullscreen","mozCancelFullScreen","webkitExitFullscreen","msExitFullscreen","documentElement","requestFullscreen","enterK","exitK","elementK","mozRequestFullScreen","webkitRequestFullscreen","msRequestFullscreen","closeOnScroll","Element","ALLOW_KEYBOARD_INPUT","PhotoSwipe","split","createElement","pageYOffset","scrollTop","RegExp","firstChild","nextSibling","arraySearch","hasOwnProperty","easing","sine","out","sin","PI","inOut","cos","cubic","detectFeatures","style","oldIE","all","touch","requestAnimationFrame","raf","caf","cancelAnimationFrame","pointerEvent","PointerEvent","navigator","msPointerEnabled","userAgent","platform","appVersion","match","isOldIOSPhone","parseFloat","androidVersion","isMobileOpera","charAt","toUpperCase","toLowerCase","Date","getTime","max","svg","createElementNS","createSVGRect","allowPanToNext","spacing","bgOpacity","loop","pinchToClose","closeOnVerticalDrag","verticalDragRange","showHideOpacity","focus","escKey","arrowKeys","mainScrollEndFriction","panEndFriction","isClickableElement","maxSpreadZoom","modal","scaleMode","ma","za","publicMethods","wa","Aa","ac","Ca","Ba","Va","initialPosition","La","min","Xa","keyCode","ctrlKey","altKey","shiftKey","metaKey","preventDefault","returnValue","Ya","Y","X","fa","Za","Ob","button","$b","U","Eb","Da","mb","pointerId","pageX","pageY","Mb","_","cb","V","ha","ka","ia","$","W","ga","Ma","oa","pa","na","kb","lb","nb","ta","ra","ob","Q","Ea","Sa","zb","Ab","aa","hb","ib","Gb","vb","ub","abs","ca","yb","Pb","tb","gb","Rb","N","4","2","3","changedTouches","sb","R","Sb","calculateSwipeSpeed","Ib","ja","db","Fa","Ha","Ub","Wb","Tb","B","M","Z","da","ea","la","qa","sa","ua","va","xa","ya","arguments","shift","bg","opacity","Ga","mc","Ia","container","Ja","Ka","Na","Oa","Pa","ic","Ta","Ua","$a","_a","ab","bb","eb","viewportSize","isMainScrollAnimating","isDragging","isZooming","applyZoomPan","framework","transform","itemHolders","el","wrap","index","display","perspective","left","height","resize","updateSize","orientationchange","clientWidth","scroll","keydown","click","animationName","ui","isNaN","_b","Line truncated
|
||||
{"version":3,"sources":["imagesloaded.pkgd.min.js","photoswipe-ui-default.min.js","photoswipe.min.js","prism.js","dropdown.js","lightbox.js","purify.min.js","reframe.min.js","casper.js","mastodon.js","pagination.js","theme.js"],"names":["e","t","define","amd","module","exports","EvEmitter","window","this","prototype","on","n","i","_events","indexOf","push","once","_onceEvents","off","length","splice","emitEvent","slice","o","r","apply","allOff","require","imagesLoaded","s","document","querySelectorAll","elements","Array","isArray","d","call","options","getImages","h","jqDeferred","Deferred","setTimeout","check","bind","a","error","img","url","element","Image","jQuery","console","u","Object","create","images","forEach","addElementImages","nodeName","addImage","background","addElementBackgroundImages","nodeType","1","9","11","getComputedStyle","exec","backgroundImage","addBackground","progress","progressedCount","hasAnyBroken","complete","isLoaded","notify","debug","log","isComplete","getIsImageComplete","confirm","naturalWidth","proxyImage","addEventListener","src","handleEvent","type","onload","unbindEvents","onerror","removeEventListener","makeJQueryPlugin","fn","promise","b","PhotoSwipeUI_Default","A","event","q","timeToIdle","mouseUsed","k","K","c","f","target","srcElement","getAttribute","g","S","onTap","name","stopPropagation","features","isOldAndroid","D","getNumItemsFn","p","C","E","y","F","removeClass","addClass","H","shareButtons","getImageURLForShare","getPageURLForShare","getTextForShare","replace","encodeURIComponent","id","download","label","parseShareButtonOut","children","innerHTML","onclick","G","I","closeElClasses","hasClass","clearTimeout","J","v","setIdle","L","relatedTarget","toElement","timeToIdleOutside","O","m","P","vGap","likelyTouchDevice","screen","width","fitControlsWidth","barsSize","captionEl","bottom","createEl","appendChild","insertBefore","addCaptionHTMLFn","clientHeight","parseInt","top","T","className","option","onInit","getChildByClass","j","l","w","x","z","loadingIndicatorDelay","title","closeEl","fullscreenEl","zoomEl","shareEl","counterEl","arrowEl","preloaderEl","tapToClose","tapToToggleControls","clickToCloseNonZoomable","currItem","location","href","indexIndicatorSep","shout","hasAttribute","open","Math","round","toggleDesktopZoom","close","prev","next","isFullscreen","exit","enter","init","extend","scrollWrap","listen","hideControls","showControls","update","initialZoomLevel","getZoomLevel","zoomTo","getDoubleTapZoom","test","tagName","prevent","onGlobalTap","onMouseOver","clearInterval","unbind","eventK","updateFullscreen","hideAnimationDuration","removeChild","showAnimationDuration","setInterval","getFullscreenAPI","template","loading","allowProgressiveImg","updateIndexIndicator","setScrollOffset","getScrollY","getCurrentIndex","detail","pointerType","fitRatio","releasePoint","supportsFullscreen","exitFullscreen","mozCancelFullScreen","webkitExitFullscreen","msExitFullscreen","documentElement","requestFullscreen","enterK","exitK","elementK","mozRequestFullScreen","webkitRequestFullscreen","msRequestFullscreen","closeOnScroll","Element","ALLOW_KEYBOARD_INPUT","PhotoSwipe","split","createElement","pageYOffset","scrollTop","RegExp","firstChild","nextSibling","arraySearch","hasOwnProperty","easing","sine","out","sin","PI","inOut","cos","cubic","detectFeatures","style","oldIE","all","touch","requestAnimationFrame","raf","caf","cancelAnimationFrame","pointerEvent","PointerEvent","navigator","msPointerEnabled","userAgent","platform","appVersion","match","isOldIOSPhone","parseFloat","androidVersion","isMobileOpera","charAt","toUpperCase","toLowerCase","Date","getTime","max","svg","createElementNS","createSVGRect","allowPanToNext","spacing","bgOpacity","loop","pinchToClose","closeOnVerticalDrag","verticalDragRange","showHideOpacity","focus","escKey","arrowKeys","mainScrollEndFriction","panEndFriction","isClickableElement","maxSpreadZoom","modal","scaleMode","ma","za","publicMethods","wa","Aa","ac","Ca","Ba","Va","initialPosition","La","min","Xa","keyCode","ctrlKey","altKey","shiftKey","metaKey","preventDefault","returnValue","Ya","Y","X","fa","Za","Ob","button","$b","U","Eb","Da","mb","pointerId","pageX","pageY","Mb","_","cb","V","ha","ka","ia","$","W","ga","Ma","oa","pa","na","kb","lb","nb","ta","ra","ob","Q","Ea","Sa","zb","Ab","aa","hb","ib","Gb","vb","ub","abs","ca","yb","Pb","tb","gb","Rb","N","4","2","3","changedTouches","sb","R","Sb","calculateSwipeSpeed","Ib","ja","db","Fa","Ha","Ub","Wb","Tb","B","M","Z","da","ea","la","qa","sa","ua","va","xa","ya","arguments","shift","bg","opacity","Ga","mc","Ia","container","Ja","Ka","Na","Oa","Pa","ic","Ta","Ua","$a","_a","ab","bb","eb","viewportSize","isMainScrollAnimating","isDragging","isZooming","applyZoomPan","framework","transform","itemHolders","el","wrap","index","display","perspective","left","height","resize","updateSize","orientationchange","clientWidth","scroll","keydown","click","animationName","ui","isNaN","_b","Line truncated
|
||||
@@ -1,6 +1,7 @@
|
||||
const MASTODON_ACCOUNT_ID = '109285376472065471'
|
||||
const MASTODON_HOST = 'social.sd.ai'
|
||||
|
||||
// Copies the text from an element to the clipboard, and flashes the element to provide visual feedback
|
||||
async function copyElementTextToClipboard(e)
|
||||
{
|
||||
const text = e.textContent
|
||||
@@ -12,6 +13,7 @@ async function copyElementTextToClipboard(e)
|
||||
}, 600);
|
||||
}
|
||||
|
||||
// sanitise text content for display
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
@@ -21,16 +23,24 @@ function escapeHtml(unsafe) {
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// renders the content - provides an array of toots, the element to add the content to and whether to show a copyable link for replies
|
||||
function renderMastodonContent(toots, parentElement, showLink) {
|
||||
// clear the parent element so that we can add the new content
|
||||
parentElement.innerHTML = ''
|
||||
// add a simple "no comments" message if there are no toots
|
||||
if (!Array.isArray(toots) || toots.length === 0) {
|
||||
document.getElementById('mastodon-comments-list').innerHTML = "<div class='mastodon-comment'>No comments (yet)!</div>"
|
||||
return
|
||||
}
|
||||
|
||||
// render each toot
|
||||
for (const toot of toots) {
|
||||
if (toot.sensitive) {
|
||||
// don't display toots marked as sensitive
|
||||
continue
|
||||
}
|
||||
|
||||
// sanitise the toot content for display, including correctly rendering custom emojis
|
||||
toot.account.display_name = escapeHtml(toot.account.display_name)
|
||||
toot.account.emojis.forEach(emoji => {
|
||||
toot.account.display_name = toot.account.display_name.replace(`:${emoji.shortcode}:`,
|
||||
@@ -40,6 +50,8 @@ function renderMastodonContent(toots, parentElement, showLink) {
|
||||
toot.content = toot.content.replace(`:${emoji.shortcode}:`,
|
||||
`<img src="${escapeHtml(emoji.static_url)}" alt="Emoji ${emoji.shortcode}" class="mastodon-emoji" />`);
|
||||
})
|
||||
|
||||
// create a block of HTML content including the toot data
|
||||
const comment =
|
||||
`<div class="mastodon-comment">
|
||||
<div class="mastodon-avatar">
|
||||
@@ -69,30 +81,44 @@ function renderMastodonContent(toots, parentElement, showLink) {
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
|
||||
// Use DOMPurify to create a sanitised element for the toot
|
||||
const child = DOMPurify.sanitize(comment, {'RETURN_DOM_FRAGMENT': true});
|
||||
|
||||
// make all toot links clickable
|
||||
const links = child.querySelectorAll('.tootlink');
|
||||
for (const link of links) {
|
||||
link.onclick = function() { return copyElementTextToClipboard(this); }
|
||||
}
|
||||
|
||||
// insert the toot into the DOM
|
||||
parentElement.appendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// We set this in the "code injection" footer for any page for which we want to enable comments
|
||||
let MASTODON_POST_ID
|
||||
|
||||
// when the page has finished loading, send a request for the toots
|
||||
document.addEventListener("DOMContentLoaded", async (event) => {
|
||||
let url, isComments
|
||||
// if we're being crawled, don't render comments - may help against spam
|
||||
const isBot = /bot|google|baidu|bing|msn|teoma|slurp|yandex/i
|
||||
.test(navigator.userAgent)
|
||||
|
||||
// if there is a sidebar, we're expecting to load the toots from the main account
|
||||
if (document.getElementsByClassName('gh-sidebar').length > 0) {
|
||||
url = `https://${MASTODON_HOST}/api/v1/accounts/${MASTODON_ACCOUNT_ID}/statuses?exclude_replies=true&exclude_reblogs=true`
|
||||
}
|
||||
// if there's a post ID and we're not a bot, we're expecting to load the replies from a specific toot
|
||||
if (MASTODON_POST_ID && !isBot) {
|
||||
url = `https://${MASTODON_HOST}/api/v1/statuses/${MASTODON_POST_ID}/context`
|
||||
isComments = true
|
||||
}
|
||||
// find the element to append the content to - if there isn't one, we don't need to query
|
||||
const element = document.getElementById('mastodon-comments-list')
|
||||
if (url && element) {
|
||||
// populate the link to the source toot, if necessary (for replies)
|
||||
const linkElement = document.getElementById('toot-link-top')
|
||||
const clipElement = document.getElementById('toot-link-clip')
|
||||
const tootUrl = `https://${MASTODON_HOST}/@s/${MASTODON_POST_ID}`
|
||||
@@ -102,11 +128,13 @@ document.addEventListener("DOMContentLoaded", async (event) => {
|
||||
if (clipElement) {
|
||||
clipElement.innerText = tootUrl
|
||||
}
|
||||
// fetch the data from Mastodon
|
||||
const response = await fetch(url)
|
||||
let content = await response.json()
|
||||
if (isComments) {
|
||||
content = content.descendants
|
||||
}
|
||||
// render the content into the page
|
||||
const header = document.getElementById('mastodon-comments-header')
|
||||
if (header) {
|
||||
header.style.display = ''
|
||||
|
||||
Reference in new issue
Block a user