Take the 2-minute tour ×
Stack Apps is a question and answer site for apps, scripts, and development with the Stack Exchange API. It's 100% free, no registration required.

About

This is a Greasemonkey script that allows you to click code regions on Stack Overflow (or other Stack Exchange sites) and have it expand to whatever size it needs. Get rid of those pesky scroll bars!

Click the code region to expand it

Features

  • Click the code region to have it expand to whatever size it needs
  • Removes vertical scroll altogether (expands to full height)
    • Intelligently expands horizontally
      • Maxes out at window width so as not to make even more scroll bars
      • If it still doesn't fit, it shrinks the font size
  • Click again to return it to normal

Download/Source

Install user script here.
(view source)

Platform

Tested in Firefox (with Greasemonkey) and Chrome.

share|improve this question
5  
awesome script! p.s. those scrollbars in the first screenshot are something else... –  Jeff Atwood Sep 5 '11 at 2:19
    
It's what I was looking for. One disadvantage is complicated text selection by touchpad –  Andy T Dec 4 '11 at 10:37
    
@AndyT - Yeah, because it just toggles on click, it can be a bit sensitive with what the browser/jQuery interprets as a click vs a text selection... Pretty easy to change the .click( to .dblclick( if you wanted it to expand on double click instead. –  Alconja Dec 4 '11 at 23:18
    
DoubleClick is often used for whole word selection. What about some small button at the top right corner. –  Andy T Dec 5 '11 at 19:37
    
...at the top right corner of code block? –  Andy T Dec 5 '11 at 19:53
2  
That'd actually be a bit better in my opinion... having a button in the top right corner of the code block... –  Thomas W. Feb 6 '12 at 18:45
    
@ThomasW., me too, and I just posted another version that works with arrows. Alconja, please, feel free to publish a new version using my mods and I'll remove the code from my answer. Thanks for the nice snippet :) –  brasofilo Oct 4 at 15:38

1 Answer 1

I adapted the script to add an arrow before any <pre> that contains scrollbars, using the following function modified to account for horizontal and vertical scrollbars.


snapshot

Here's the script in action in some innocent code blocks that have lots of hidden stuff.
GIF recorded before moving the arrows to the right.


anim

It only runs when viewing a question or doing some review task.

// ==UserScript==
// @name          Expand code blocks on Stack Exchange sites
// @namespace     stackapps
// @description   Click a code block with scroll bars and it automatically expands
// @match         *://*.askubuntu.com/questions*
// @match         *://*.askubuntu.com/review*
// @match         *://*.mathoverflow.net/questions*
// @match         *://*.mathoverflow.net/review*
// @match         *://*.serverfault.com/questions*
// @match         *://*.serverfault.com/review*
// @match         *://*.stackapps.com/questions*
// @match         *://*.stackapps.com/review*
// @match         *://*.stackexchange.com/questions*
// @match         *://*.stackexchange.com/review*
// @match         *://*.stackoverflow.com/questions*
// @match         *://*.stackoverflow.com/review*
// @match         *://*.superuser.com/questions*
// @match         *://*.superuser.com/review*
// @exclude       *://chat.*
// @exclude       *://blog.*
// @exclude       *://api.*
// @exclude       *://data.*
// @grant         none
// @author        Alconja
// @contributor   brasofilo
// ==/UserScript==

/**
 * Adapted from http://stackoverflow.com/a/8971716/1287812
 */
$.fn.has_scrollbar = function() {
    var divnode = this.get(0);
    if(divnode.scrollHeight > divnode.clientHeight || divnode.scrollWidth > divnode.clientWidth )
        return true;
}

/**
 * Expand <pre>
 */
function expando( pre ) {
    var maxHeight = null;
    pre.css("z-index", 1000);
    var code = pre.children("code");
    if (maxHeight === null) {
        maxHeight = pre.css("max-height");
        if( pre.attr('max-height') === undefined )
            pre.attr('max-height',maxHeight);
    }
    var oldWidth = pre.width();
    var codeWidth = Math.max(code.width(), oldWidth);
    var maxWidth = $(window).width() - 20;
    var width = Math.min(maxWidth, codeWidth);

    var maxLeft = (-1 * pre.offset().left) + 5;
    var idealLeft = (oldWidth - width) / 2.0;
    var left = Math.max(maxLeft, idealLeft);
    pre.css({width: width + "px", position: "relative", left: left + "px", maxHeight: "inherit"});
    if (width < codeWidth) {                //last ditch attempt to fit...
        var pc = 100 * width / codeWidth;
        pc = Math.max(pc, 70);              //any smaller & you can't read it...
        pre.css("font-size", pc + "%");
    }
}

/**
 * Contract <pre>
 */
function contracto( pre ) {
    pre.css({width: "auto", position: "static", maxHeight: pre.attr('max-height'), fontSize: "100%"});
}

/**
 * Check page and add arrows
 */
function addArrows() {
    var count_pre = 1;
    $('pre').each(function(){ 
        if( $(this).has_scrollbar() ) {
            $(this).before('<span class="expander-arrow-small-hide" id="expander-id-' + count_pre + '" style="float:right"></span>'); 
            $('#expander-id-'+count_pre).click(function(){
                if( $(this).hasClass('expander-arrow-small-hide') ){
                    expando( $(this).next() );
                    $(this).removeClass('expander-arrow-small-hide').addClass('expander-arrow-small-show');
                }
                else {
                    contracto( $(this).next() );
                    $(this).removeClass('expander-arrow-small-show').addClass('expander-arrow-small-hide');
                }
            }).css('cursor','pointer');
            count_pre++;
        }
    });
}

/**
 * Run when reviewing
 */
if( StackExchange.options.routeName === 'Review/Task' ) {
    $(document).ajaxComplete(function( event, xhr, settings ){
        if( settings.url.indexOf('review/task-reviewed') !== -1 || settings.url.indexOf('review/next-task') !== -1 ) {
            addArrows();
        }
    });
}

/**
 * Run when viewing a question
 */
if( StackExchange.options.routeName == "Questions/Show" ) {
    // Only SO has this property as visible, which is needed to fully expand the blocks 
    if( location.host !== 'stackoverflow.com' && location.host !== 'meta.stackoverflow.com' ) {
        if( $('#content').css('overflow') === 'auto' )
            $('#content').css('overflow','visible');
    }
    addArrows();
}

Install

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .