/* * DisqusJS | v0.1.4 * Author: SukkaW * Link: https://github.com/SukkaW/DisqusJS * License: GPL-3.0 */ /* * The variable used in DisqusJS * * DisqusJS Mode * disqusjs.mode = dsqjs | disqus - Set which mode to use, should store and get in localStorage * * DisqusJS Config * disqusjs.config.shortname - The disqus shortname * disqusjs.config.identifier - The identifier of the page * disqusjs.config.url - The url of the page * disqusjs.config.api - Where to get data * disqusjs.config.apikey - The apikey used to request Disqus API * disqusjs.config.admin - The disqus forum admin username * disqusjs.config.adminLabel - The disqus moderator badge text * * DisqusJS Info * disqusjs.page.id = The thread id, used at next API call * disqusjs.page.title - The thread title * disqusjs.page.isClosed - Whether the comment is closed * disqusjs.page.lenfth - How many comment in this thread */ (function () { disqusjs.page = []; window.disqus_config = function () { this.page.url = disqusjs.config.url; this.page.identifier = disqusjs.config.identifier; }; var xhr = new XMLHttpRequest(); let setLS = (key, value) => { try { localStorage.setItem(key, value); } catch (o) { console.log(o + " Failed to set localStorage item"); } }, getLS = (key) => { return localStorage.getItem(key); }, dateFormat = (date) => { return `${date.getUTCFullYear().toString()}/${(date.getUTCMonth() + 1).toString()}/${date.getUTCDate()} ${date.getUTCHours()}:${date.getUTCMinutes()}:${date.getUTCSeconds()}` //yyyy-MM-dd hh:mm:ss } /* * Name: loadDisqus() * Descriptin: load disqus as it should be. */ let loadDisqus = () => { var d = document; d.getElementById('dsqjs-load-disqus').classList.remove('dsqjs-hide'); d.getElementById('dsqjs-force-dsqjs').addEventListener('click', forceDsqjs); var s = d.createElement('script'); s.src = 'https://' + disqusjs.config.shortname + '.disqus.com/embed.js'; s.setAttribute('data-timestamp', + new Date()); (d.head || d.body).appendChild(s); } /* * Name: checkDisqus() * Description: Check disqus is avaliable for visitor or not * How it works: check favicons under 2 domains can be loaded or not. */ let checkDisqus = () => { var img = new Image; let check1 = setTimeout(() => { img.onerror = img.onload = null; setLS('disqusjs_mode', 'dsqjs'); }, 2000); img.onerror = () => { clearTimeout(check1); setLS('disqusjs_mode', 'dsqjs'); main(); }; img.onload = () => { clearTimeout(check1); let check2 = setTimeout(() => { img.onerror = img.onload = null; setLS('disqusjs_mode', 'dsqjs'); }, 2000); img.onerror = () => { clearTimeout(check2); setLS('disqusjs_mode', 'dsqjs'); main(); }; img.onload = () => { clearTimeout(check2); setLS('disqusjs_mode', 'disqus'); main(); }; img.src = 'https://' + disqusjs.config.shortname + '.disqus.com/favicon.ico?' + +(new Date); }; img.src = 'https://disqus.com/favicon.ico?' + +(new Date); } /* * Name: forceDsqjs() forceDisqus() */ let forceDsqjs = () => { setLS('disqusjs_mode', 'dsqjs'); main(); } let forceDisqus = () => { setLS('disqusjs_mode', 'disqus'); main(); } /* * Name: getThreadInfo() * Description: Disqus API only support get thread list by ID, not identifter. So get Thread ID before get thread list. * API Docs: https://disqus.com/api/docs/threads/list/ * API URI: /3.0/threads/list.json?forum=[disqus_shortname]&thread=ident:[identifier]&api_key=[apikey] */ let getThreadInfo = () => { document.getElementById('dsqjs-loading-dsqjs').classList.remove('dsqjs-hide'); document.getElementById('dsqjs-load-error').classList.add('dsqjs-hide'); document.getElementById('dsqjs-force-disqus').addEventListener('click', forceDisqus); document.getElementById('dsqjs-reload-disqus').addEventListener('click', checkDisqus); let url = disqusjs.config.api + '3.0/threads/list.json?forum=' + disqusjs.config.shortname + '&thread=ident:' + disqusjs.config.identifier + '&api_key=' + disqusjs.config.apikey; xhr.open('GET', url, true); xhr.timeout = 4000; xhr.send(); xhr.onload = function () { if (this.status === 200 || this.status === 304) { let res = JSON.parse(this.responseText).response; if (res.length === 1) { var response = res[0]; disqusjs.page = { id: response.id, title: response.title, isClosed: response.isClosed, length: response.posts }; getComment(); } else { document.getElementById('dsqjs-thread-not-init').classList.remove('dsqjs-hide'); document.getElementById('dsqjs-init-thread').addEventListener('click', forceDisqus); } } else { loadError(); } }; xhr.ontimeout = (e) => { loadError(); }; xhr.onerror = (e) => { loadError(); }; } /* * Name: getComment() * Description: get the comment content * API URI: /3.0/posts/list.json?forum=[shortname]&thread=[thread id]&api_key=[apikey] */ let getComment = () => { let url = disqusjs.config.api + '3.0/posts/list.json?forum=' + disqusjs.config.shortname + '&thread=' + disqusjs.page.id + '&api_key=' + disqusjs.config.apikey; xhr.open('GET', url, true); xhr.timeout = 4000; xhr.send(); xhr.onload = function () { if (this.status === 200 || this.status === 304) { var res = JSON.parse(this.responseText); if (res.code === 0 && res.response.length > 0) { getCommentList(res.response); } else if (res.code === 0 && res.response.length === 0) { // Have no comments. document.getElementById('dsqjs-no-comment').classList.remove('dsqjs-hide'); } } else { loadError(); } }; xhr.ontimeout = (e) => { // Have error when get comments. loadError(); }; xhr.onerror = (e) => { // Have error when get comments. loadError(); }; } /* * Name: getCommentList(data) * Description: Render JSON to comment list components */ let getCommentList = (data) => { var topLevelComments = []; var childComments = []; data.forEach(comment => { (comment.parent ? childComments : topLevelComments)['push'](comment) }) var commentLists = topLevelComments.map(comment => { return { comment, author: comment.author.name, isPrimary: comment.author.username === disqusjs.config.admin.toLowerCase(), children: getChildren(+comment.id) }; }); function getChildren(id) { if (childComments.length === 0) return null; var list = []; for (let comment of childComments) { if (comment.parent === id) { list.unshift({ comment, author: comment.author.name, isPrimary: comment.author.username === disqusjs.config.admin.toLowerCase(), children: getChildren(+comment.id) }); } } if (list.length) { return list; } else { return null; } } renderComment(commentLists) } let renderComment = (data) => { let renderCommentItem = (s) => { /*
${s.avatarEl}
${s.authorEl}
${s.message}
*/ let commentItemTpl = `
${s.avatarEl}
${s.authorEl}
${s.message}
` return commentItemTpl } data.map(s => { let childrenComments = (s) => { var nesting = s.nesting var children = (s.children || []); if (typeof children === 'null') { return; } if (nesting < 4) { var html = '