// ==UserScript== // @name Expand code blocks on Stack Exchange sites // @namespace stackapps // @version 1.1 // @description Click a code block with scroll bars and it automatically expands // @icon http://i.stack.imgur.com/EmeVj.png // @match *://*.serverfault.com/questions* // @match *://*.serverfault.com/review* // @match *://*.stackapps.com/questions* // @match *://*.stackapps.com/review* // @match *://*.stackoverflow.com/questions* // @match *://*.stackoverflow.com/review* // @match *://*.superuser.com/questions* // @match *://*.superuser.com/review* // @match *://*.wordpress.stackexchange.com/questions* // @match *://*.wordpress.stackexchange.com/review* // @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
 */
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) / 4.5;
    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 
 */
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(''); 
            $('#expander-id-'+count_pre).click(function(){
                if( $(this).hasClass('expander-arrow-small-hide') ){
                    expando( $(this).next() );
                    if( location.host.indexOf('wordpress.stackexchange') > -1 ) {
                        $('#content').css('overflow','visible');
                    }
                    $(this).removeClass('expander-arrow-small-hide').addClass('expander-arrow-small-show');
                }
                else {
                    if( location.host.indexOf('wordpress.stackexchange') > -1 ) {
                        $('#content').css('overflow','auto');
                    }
                    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.indexOf('stackoverflow.com') === -1 && location.host.indexOf('wordpress.stackexchange') === -1  ) {
        if( $('#content').css('overflow') === 'auto' )
            $('#content').css('overflow','visible');
    }
    addArrows();
}