// ==UserScript==
// @name StackExchange Legacy Comments Expander
// @namespace https://github.com/StaticPH
// @match https://askubuntu.com/*
// @match https://serverfault.com/*
// @match https://superuser.com/*
// @match https://stackoverflow.com/*
// @match https://stackexchange.com/*
// @match https://*.stackoverflow.com/*
// @match https://*.stackexchange.com/*
// @version 1.2.0
// @createdAt 11/6/2022, 1:17:14 AM
// @author StaticPH
// @description Replace 'Show X more comments' handler for StackExchange sites to better support older browsers; in particular, this enables showing all comments when using Chromium 72.
// @license MIT
// @updateURL https://raw.githubusercontent.com/StaticPH/Userscripts/master/legacy_browser_workarounds/stackexchange_legacy_comments_expander.user.js
// @downloadURL https://raw.githubusercontent.com/StaticPH/Userscripts/master/legacy_browser_workarounds/stackexchange_legacy_comments_expander.user.js
// @homepageURL https://github.com/StaticPH/UserScripts
// @supportURL https://github.com/StaticPH/UserScripts/issues
// @icon https://cdn.sstatic.net/Sites/stackoverflow/Img/favicon.ico
// @grant none
// @noframes
// @run-at document-idle
// ==/UserScript==
(function(){
'use strict';
function replaceChildrenWithNodes(parentNode, ...newChildren){
while (parentNode.lastChild){
parentNode.lastChild.remove();
}
if (newChildren !== undefined){
const replacements = (newChildren.length === 1 && Array.isArray(newChildren[0])) ? newChildren[0] : newChildren;
parentNode.append(...replacements);
return true;
}
return false;
}
function replaceChildrenWithFetched(parentEle, rawHtml){
const parser = new DOMParser();
const responseHtml = parser.parseFromString(rawHtml, 'text/html');
return replaceChildrenWithNodes(parentEle, ...responseHtml.querySelectorAll('li'));
}
function replaceCommentsListFromFetched(insertInto, data){
const parser = new DOMParser();
const responseHtml = parser.parseFromString(`
`, 'text/html');
return replaceChildrenWithNodes(insertInto, responseHtml.body.firstElementChild);
}
const replySVG = '';
const commentUpvoteSVG = '';
const ellipsesSVG = '';
// oxlint-disable no-unused-vars
function buildReplyTemplate(reply, postID){
return `
${reply.user.displayName}
${reply.htmlBody}
`;
}
function onExpandComments(evnt){
if (evnt.target.matches('.answer a.js-show-link, .question a.js-show-link')){
evnt.stopImmediatePropagation();
evnt.preventDefault();
const answer = evnt.target.closest('.answer, .question');
const postID = answer.getAttribute('data-answerid') || answer.getAttribute('data-questionid');
const insertInto = answer.querySelector('ul.comments-list');
fetch(document.location.origin + '/posts/' + postID + '/comments', {
'headers': {
'accept': 'text/html, */*; q=0.01',
},
'referrerPolicy': 'strict-origin-when-cross-origin',
'body': null,
'method': 'GET',
'mode': 'cors',
'credentials': 'include'
}).then(resp => resp.text())
/*
.then(data => replaceChildrenWithFetched(insertInto, data))
.then(()=>{
evnt.target.parentElement.remove();
insertInto.setAttribute('data-remaining-comments-count', '0');
});
*/
.then(data => replaceChildrenWithFetched(insertInto, data) && evnt.target.parentElement.remove())
.catch(insertInto.setAttribute('data-remaining-comments-count', '0'));
}
else if (evnt.target.matches('.answer button.comments-link:not([data-so-test*="parent-answer"])')){
evnt.stopImmediatePropagation();
evnt.preventDefault();
const answer = evnt.target.closest('.answer');
const postID = answer.getAttribute('data-answerid') || answer.getAttribute('data-questionid');
const followupScriptEle = answer.querySelector('script[type="application/json"]');
const followupData = JSON.parse(followupScriptEle.textContent);
const insertInto = answer.querySelector(`#${followupData.containerElementId} [role="list"]`);
// for (reply of followupData.replies){
// insertInto.insertAdjacentHTML('beforeEnd', buildReplyTemplate(reply, postID)); // Doesn't fix the order to be chronological, and that seems like a hassle.
//}
fetch(`${document.location.origin}/posts/${postID}/comments`, {
'headers': {
'accept': 'text/html, */*; q=0.01',
},
'referrerPolicy': 'strict-origin-when-cross-origin',
'body': null,
'method': 'GET',
'mode': 'cors',
'credentials': 'include'
}).then(resp => resp.text())
.then(data => requestAnimationFrame(function(){
if (replaceCommentsListFromFetched(insertInto, data)){
evnt.target.parentElement.remove();
}
insertInto.setAttribute('data-remaining-comments-count', '0');
}));
}
}
// Relevant if using buildReplyTemplate
// document.head.insertAdjacentHTML('beforeEnd', '');
document.addEventListener('click', onExpandComments);
})();