/** * Mastodon embed feed timeline * @author idotj * @version 4.0.4 * @url https://gitlab.com/idotj/mastodon-embed-feed-timeline * @license GNU AGPLv3 */ "use strict";class MastodonTimeline{constructor(t={}){this.defaultSettings={mtContainerId:"mt-container",instanceUrl:"https://mastodon.social",timelineType:"local",userId:"",profileName:"",hashtagName:"",spinnerClass:"mt-loading-spinner",defaultTheme:"auto",maxNbPostFetch:"20",maxNbPostShow:"20",hideUnlisted:!1,hideReblog:!1,hideReplies:!1,hideVideoPreview:!1,hidePreviewLink:!1,hideEmojos:!1,markdownBlockquote:!1,hideCounterBar:!1,txtMaxLines:"0",btnShowMore:"SHOW MORE",btnShowLess:"SHOW LESS",btnShowContent:"SHOW CONTENT",btnSeeMore:"See more posts at Mastodon",btnReload:"Refresh"},this.mtSettings={...this.defaultSettings,...t},this.mtContainerNode="",this.mtBodyNode="",this.fetchedData={},this.mtInit()}onDOMContentLoaded(t){"undefined"!=typeof document&&("complete"===document.readyState||"interactive"===document.readyState)?t():"undefined"!=typeof document&&("complete"!==document.readyState||"interactive"!==document.readyState)&&document.addEventListener("DOMContentLoaded",t)}mtInit(){this.onDOMContentLoaded(()=>{this.mtContainerNode=document.getElementById(this.mtSettings.mtContainerId),this.mtBodyNode=this.mtContainerNode.getElementsByClassName("mt-body")[0],this.#a(),this.#b("newTimeline")})}mtUpdate(){this.onDOMContentLoaded(()=>{this.mtBodyNode.replaceChildren(),this.mtBodyNode.insertAdjacentHTML("afterbegin",'
'),this.#b("updateTimeline")})}mtColorTheme(t){this.onDOMContentLoaded(()=>{this.mtContainerNode.setAttribute("data-theme",t)})}#a(){if("auto"===this.mtSettings.defaultTheme){let t=window.matchMedia("(prefers-color-scheme: dark)");t.matches?this.mtColorTheme("dark"):this.mtColorTheme("light"),t.addEventListener("change",t=>{t.matches?this.mtColorTheme("dark"):this.mtColorTheme("light")})}else this.mtColorTheme(this.mtSettings.defaultTheme)}#c(){return new Promise((t,e)=>{async function s(t){let e=await fetch(t);if(!e.ok)throw Error("Failed to fetch the following Url:
"+t+"
Error status: "+e.status+"
Error message: "+e.statusText);let s=await e.json();return s}let i={};this.mtSettings.instanceUrl?"profile"===this.mtSettings.timelineType?this.mtSettings.userId?i.timeline=`${this.mtSettings.instanceUrl}/api/v1/accounts/${this.mtSettings.userId}/statuses?limit=${this.mtSettings.maxNbPostFetch}`:this.#d("Please check your userId value","⚠️"):"hashtag"===this.mtSettings.timelineType?this.mtSettings.hashtagName?i.timeline=`${this.mtSettings.instanceUrl}/api/v1/timelines/tag/${this.mtSettings.hashtagName}?limit=${this.mtSettings.maxNbPostFetch}`:this.#d("Please check your hashtagName value","⚠️"):"local"===this.mtSettings.timelineType?i.timeline=`${this.mtSettings.instanceUrl}/api/v1/timelines/public?local=true&limit=${this.mtSettings.maxNbPostFetch}`:this.#d("Please check your timelineType value","⚠️"):this.#d("Please check your instanceUrl value","⚠️"),this.mtSettings.hideEmojos||(i.emojos=this.mtSettings.instanceUrl+"/api/v1/custom_emojis");let a=Object.entries(i).map(([t,i])=>s(i).then(e=>({[t]:e})).catch(s=>(e(Error("Something went wrong fetching data from: "+i)),this.#d(s.message),{[t]:[]})));Promise.all(a).then(e=>{this.mtSettings.fetchedData=e.reduce((t,e)=>({...t,...e}),{}),t()})})}async #b(e){await this.#c(),this.mtBodyNode.replaceChildren();let s=0;for(let i in this.mtSettings.fetchedData.timeline)("public"==this.mtSettings.fetchedData.timeline[i].visibility||!this.mtSettings.hideUnlisted&&"unlisted"==this.mtSettings.fetchedData.timeline[i].visibility)&&(this.mtSettings.hideReblog&&this.mtSettings.fetchedData.timeline[i].reblog||this.mtSettings.hideReplies&&this.mtSettings.fetchedData.timeline[i].in_reply_to_id||sThis may be due to an incorrect configuration in the parameters or to filters applied (to hide certains type of posts)";this.#d(a,"\uD83D\uDCED")}else"newTimeline"===e?(this.#f(),this.#g(),this.#h()):"updateTimeline"===e?this.#f():this.#d("The function buildTimeline() was expecting a param")}#e(o,n){this.mtBodyNode.insertAdjacentHTML("beforeend",this.#i(o,n))}#i(r,l){let m,d,h,c,p,g,u,v,b;r.reblog?(c=r.reblog.url,m='
'+this.#j(r.reblog.account.username)+' avatar
'+this.#j(r.account.username)+' avatar
',h=r.reblog.account.display_name?r.reblog.account.display_name:r.reblog.account.username,this.mtSettings.hideEmojos||(h=this.#k(h,this.mtSettings.fetchedData.emojos)),d='
'+h+' account
',p=r.reblog.created_at,b=r.reblog.replies_count,v=r.reblog.reblogs_count,u=r.reblog.favourites_count):(c=r.url,m='
'+this.#j(r.account.username)+' avatar
',h=r.account.display_name?r.account.display_name:r.account.username,this.mtSettings.hideEmojos||(h=this.#k(h,this.mtSettings.fetchedData.emojos)),d='
'+h+' account
',p=r.created_at,b=r.replies_count,v=r.reblogs_count,u=r.favourites_count),g=this.#l(p);let S='
",$="";"0"!==this.mtSettings.txtMaxLines&&($=" truncate",this.mtBodyNode.parentNode.style.setProperty("--mt-txt-max-lines",this.mtSettings.txtMaxLines));let f="";f=""!==r.spoiler_text?'
'+r.spoiler_text+'
'+this.#m(r.content)+"
":r.reblog&&""!==r.reblog.content&&""!==r.reblog.spoiler_text?'
'+r.reblog.spoiler_text+'
'+this.#m(r.reblog.content)+"
":r.reblog&&""!==r.reblog.content&&""===r.reblog.spoiler_text?'
'+this.#m(r.reblog.content)+"
":'
'+this.#m(r.content)+"
";let _=[];if(r.media_attachments.length>0)for(let w in r.media_attachments)_.push(this.#n(r.media_attachments[w],r.sensitive));if(r.reblog&&r.reblog.media_attachments.length>0)for(let y in r.reblog.media_attachments)_.push(this.#n(r.reblog.media_attachments[y],r.reblog.sensitive));let N="";!this.mtSettings.hidePreviewLink&&r.card&&(N=this.#o(r.card));let x="";if(r.poll){let L="";for(let T in r.poll.options)L+="
  • "+r.poll.options[T].title+"
  • ";x='
    "}let C="";if(!this.mtSettings.hideCounterBar){let M='
    '+b+"
    ",k='
    '+v+"
    ",E='
    '+u+"
    ";C='
    '+M+k+E+"
    "}let P='
    '+m+d+S+"
    "+f+_.join("")+N+x+C+"
    ";return P}#m(B){let H=B;return H=this.#p(H),this.mtSettings.hideEmojos||(H=this.#k(H,this.mtSettings.fetchedData.emojos)),this.mtSettings.markdownBlockquote&&(H=this.#q(H,"

    >","

    ","

    ","

    ")),H}#p(j){let A=j.replaceAll('rel="tag"','rel="tag" target="_blank"');return A.replaceAll('class="u-url mention"','class="u-url mention" target="_blank"')}#q(D,U,I,O,F){if(!D.includes(U))return D;{let R=RegExp(U+"(.*?)"+I,"gi");return D.replace(R,O+"$1"+F)}}#j(z){return(z??"").replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}#k(q,Z){if(!q.includes(":"))return q;for(let V of Z){let J=RegExp(`\\:${V.shortcode}\\:`,"g");q=q.replace(J,`Emoji ${V.shortcode}`)}return q}#l(W){let Y=new Date(W),G=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",][Y.getMonth()]+" "+Y.getDate()+", "+Y.getFullYear();return G}#n(K,Q){let X=Q||!1,tt=K.type,te="";return"image"===tt&&(te='
    '+(X?'":"")+''+(K.description?this.#j(K.description):
    '),"audio"===tt&&(te=K.preview_url?'
    '+(X?'":"")+''+(K.description?this.#j(K.description):
    ':'
    '+(X?'":"")+'
    '),("video"===tt||"gifv"===tt)&&(te=this.mtSettings.hideVideoPreview?'
    '+(X?'":"")+'
    ':'
    '+(X?'":"")+''+(K.description?this.#j(K.description):
    '),te}#r(ts){let ti=ts.target.closest("[data-video-url]"),ta=ti.dataset.videoUrl;ti.replaceChildren(),ti.innerHTML=''}#s(to){let tn=to.target.nextSibling;"img"===tn.localName||"audio"===tn.localName||"video"===tn.localName?(to.target.parentNode.classList.remove("mt-post-media-spoiler"),to.target.style.display="none"):(tn.classList.contains("spoiler-txt-hidden")||tn.classList.contains("spoiler-txt-visible"))&&(to.target.textContent==this.mtSettings.btnShowMore?(tn.classList.remove("spoiler-txt-hidden"),tn.classList.add("spoiler-txt-visible"),to.target.setAttribute("aria-expanded","true"),to.target.textContent=this.mtSettings.btnShowLess):(tn.classList.remove("spoiler-txt-visible"),tn.classList.add("spoiler-txt-hidden"),to.target.setAttribute("aria-expanded","false"),to.target.textContent=this.mtSettings.btnShowMore))}#o(tr){let tl=''+(tr.image?'
    '+this.#j(tr.image_description)+'
    ':'
    \uD83D\uDCC4
    ')+'
    '+(tr.provider_name?''+this.#t(tr.provider_name)+"":"")+''+tr.title+""+(tr.author_name?''+this.#t(tr.author_name)+"":"")+"
    ";return tl}#t(tm){let td=new DOMParser,th=td.parseFromString(tm,"text/html");return th.body.textContent}#h(){if(this.mtSettings.btnSeeMore||this.mtSettings.btnReload){this.mtBodyNode.parentNode.insertAdjacentHTML("beforeend",'');let tc=this.mtContainerNode.getElementsByClassName("mt-footer")[0];if(this.mtSettings.btnSeeMore){let tp="";"profile"===this.mtSettings.timelineType?this.mtSettings.profileName?tp=this.mtSettings.profileName:this.#d("Please check your profileName value","⚠️"):"hashtag"===this.mtSettings.timelineType?tp="tags/"+this.mtSettings.hashtagName:"local"===this.mtSettings.timelineType&&(tp="public/local");let tg=''+this.mtSettings.btnSeeMore+"";tc.insertAdjacentHTML("beforeend",tg)}if(this.mtSettings.btnReload){let tu='";tc.insertAdjacentHTML("beforeend",tu);let tv=this.mtContainerNode.getElementsByClassName("btn-refresh")[0];tv.addEventListener("click",()=>{this.mtUpdate()})}}}#g(){this.mtBodyNode.addEventListener("click",t=>{"article"!=t.target.localName&&t.target.offsetParent?.localName!="article"&&("img"!=t.target.localName||t.target.parentNode.getAttribute("data-video-url"))||this.#u(t),"button"==t.target.localName&&t.target.classList.contains("mt-btn-spoiler")&&this.#s(t),("mt-post-media-play-icon"==t.target.className||"svg"==t.target.localName&&"mt-post-media-play-icon"==t.target.parentNode.className||"path"==t.target.localName&&"mt-post-media-play-icon"==t.target.parentNode.parentNode.className||"img"==t.target.localName&&t.target.parentNode.getAttribute("data-video-url"))&&this.#r(t)}),this.mtBodyNode.addEventListener("keydown",t=>{"Enter"===t.key&&"article"==t.target.localName&&this.#u(t)})}#u(tb){let tS=tb.target.closest(".mt-post").dataset.location;"a"!==tb.target.localName&&"span"!==tb.target.localName&&"button"!==tb.target.localName&&"time"!==tb.target.localName&&"mt-post-preview-noImage"!==tb.target.className&&"mt-post-avatar-image-big"!==tb.target.parentNode.className&&"mt-post-avatar-image-small"!==tb.target.parentNode.className&&"mt-post-preview-image"!==tb.target.parentNode.className&&"mt-post-preview"!==tb.target.parentNode.className&&tS&&window.open(tS,"_blank","noopener")}#f(){let t$=t=>{t.target.parentNode.classList.remove(this.mtSettings.spinnerClass),t.target.removeEventListener("load",t$),t.target.removeEventListener("error",t$)};this.mtBodyNode.querySelectorAll(`.${this.mtSettings.spinnerClass} > img`).forEach(t=>{t.addEventListener("load",t$),t.addEventListener("error",t$)})}#d(tf,t_){throw this.mtBodyNode.innerHTML='
    '+(t_||"❌")+'
    Oops, something\'s happened:
    '+tf+"
    ",this.mtBodyNode.setAttribute("role","none"),Error("Stopping the script due to an error building the timeline.")}}