1

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!

You must log in to answer this question.

Browse other questions tagged .