In principle that what Expand all comments script does, but with two major differences:
- Scrolls the page back to the initial target of the corresponding link you selected (i.e. to question, question comment, answer or answer comment) after comment expansion (since also "clicking" on a link programmatically – show n more comments in this case – scrolls the page to that link).
- [internal] Uses regex for
@include
and@exclude
. (Agreed, this prevents the really nice Sites favicons in Tampermonkey's Installed userscripts tab.)
// ==UserScript==
// @name StackExchange – Expand Hidden Comments
// @description Expands hidden comments of SE questions and answers on sites with the new naming convention <something>.stackexchange.com and on Ask Ubuntu, Code Review, Server Fault, Super User and MathOverflow (the script is easily adaptable for more).
// @version 19.12.1
// @icon https://upload.wikimedia.org/wikipedia/commons/5/5a/Icons-mini-comment_yellow.gif
// @author Gerold 'Geri' Broser <https://stackoverflow.com/users/1744774>
// @license GNU GPLv3 <http://www.gnu.org/licenses/gpl-3.0.html>
// @homepage https://stackapps.com/questions/8514
// @supportURL https://stackapps.com/questions/8514
// ------------
@include /^https:\/\/(\w*\.+)?(stack|ask|code|server|super|math)\w*\.(com|net)\/questions\/?.*$/
// Matches: |<none> || ⬑– Domains that don't follow | | TLDs || Paths |
// |meta. || the <something>.stackexchange| | + possible |
// | || scheme... | | fragment |
// |⬑–––––––⬑–––– ...and those that do. |
// @exclude /^https:\/\/(\w*\.+)?(stack|ask|code|server|super|math)\w*\.(com|net)\/questions\/ask\/?.*$/
// Matches: |<none> || ⬑– Domains that don't follow | | TLDs || Path |
// |meta. || the <something>.stackexchange| |+ possible fragment|
// | || scheme... |
// |⬑–––––––⬑–––– ...and those that do. |
// ---- extend bracket expression(s) above for new site(s) ----
// @namespace igb
// @grant none
// ==/UserScript==
(function() {
'use strict'
try {
console.log("BEGIN StackExchange – Expand Hidden Comments...");
// Get top first element in viewport to scroll to it after expansion, such restoring the viewport view.
// The top first element can be one of the following:
// - a question (i.e. top of the page)
// - a question comment --+
// - an answer +--> opened via a corresponding link
// - an answer cpmment --+
let topFirst = void(0)
// Is question top first?
const search = document.getElementById('search')
topFirst = search.getBoundingClientRect().top > 0 ? search.parentNode : void(0)
//console.debug("Is question top first?...", topFirst === void(0) ? "No" : "Yes")
if ( topFirst === void(0) ) {
// Is question comment top first?
let questionComment = void(0)
for ( questionComment of document.querySelectorAll('div#question div.comment-text') ) {
//console.debug(questionComment, questionComment.getBoundingClientRect().top)
if ( questionComment.getBoundingClientRect().top > 0 ) {
topFirst = questionComment
break
} // if
} // for
//console.debug("Is question comment top first?...", topFirst === void(0) ? "No" : "Yes")
} // if
let answer = void(0)
if ( topFirst === void(0) ) {
// Is answer top first?
for ( answer of document.getElementsByClassName('answercell') ) {
//console.debug("answer:", answer, answer.getBoundingClientRect().top)
if ( answer.getBoundingClientRect().top > 0 ) {
topFirst = answer
break
}
else {
// Is answer comment top first?
let answerComment = void(0)
for ( answerComment of document.querySelectorAll('div#answers div.comment-text') ) {
//console.debug("answerComment:", answerComment, answerComment.getBoundingClientRect().top)
if ( answerComment.getBoundingClientRect().top > 0 ) {
topFirst = answerComment
break
} // if
} // for ( answer comments )
//console.debug("Is answer comment top first?...", topFirst === void(0) ? "No" : "Yes")
if ( topFirst !== void(0) )
break
} // if
} // for ( answers )
//console.debug("Is answer top first?...", topFirst === answer ? "Yes" : "No")
} // if
[...document.getElementsByClassName('js-show-link')].forEach( link => {
link.click() // scrolls page till last clicked link, therefore view is saved above and restored below
})
setTimeout( () => {
console.log('BEGIN StackExchange – Expand Hidden Comments...delayed...')
// Restore viewport view
topFirst.scrollIntoView(true)
//console.debug(topFirst, topFirst.getBoundingClientRect().top)
console.log("END StackExchange – Expand Hidden Comments...delayed.")
}, 1000 ) // increase if time isn't enough to scroll view to initial position
console.log("END StackExchange – Expand Hidden Comments.")
}
catch (e) {
console.error(e)
}
})();
(Possible) TODO
- Use jQuery to become browser agnostic if according issues arise.
Hints for improvement are welcome!