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.

Shows a select-button on mouse over on code-blocks to select the whole block for easier copying.

Sorry to not provide a file for download but i am sure you will manage somehow, adjust includes as needed:

// ==UserScript==
// @name           Select Code Block Buttons
// @namespace      stackoverflow
// @include        *stackoverflow.com*
// ==/UserScript==

(function ()
{
    function with_jquery(f)
    {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.textContent = "(" + f.toString() + ")(jQuery)";
        document.body.appendChild(script);
    };

    with_jquery(function ($)
    {
        addButtons();

        function selectText(element)
        {
            var doc = document;
            if (doc.body.createTextRange)
            {
                var range = doc.body.createTextRange();
                range.moveToElementText(element);
                range.select();
            } else if (window.getSelection)
            {
                var selection = window.getSelection();
                var range = doc.createRange();
                range.selectNodeContents(element);
                selection.removeAllRanges();
                selection.addRange(range);
            }
        }

        function addButtons()
        {
            $("pre").each(function (i, codeBlock)
            {
                var qContainer = $("<div></div>");
                var id = "select-button-" + i;
                $(codeBlock).replaceWith(qContainer);
                qContainer.append(codeBlock);

                qContainer.mouseenter(function ()
                {
                    var qButton = $('<div style="position: absolute; opacity: 0; display: inline; cursor: pointer;' +
                                     'background-color: #000; color: #fff; font-size: 12pt; padding: 3px;">' +
                                     'Select</div>');
                    qButton.attr("id", id);
                    qContainer.append(qButton);
                    var left = $(codeBlock).offset().left + $(codeBlock).width() - qButton.width();
                    var top = $(codeBlock).offset().top;
                    qButton.css("left", left);
                    qButton.css("top", top);
                    qButton.click(function ()
                    {
                        selectText(codeBlock);
                    });
                    qButton.stop(true, true).animate({ opacity: '+=0.6' });
                });
                qContainer.mouseleave(function ()
                {
                    $("#" + id).stop(true, true).animate({ opacity: '-=0.6' }, function () { $("#" + id).remove(); });
                });
            });
        }
    });
})();

Edits:

  • Buttons are now created on mouse-over, making sure that the placement is correct as the layout may change (e.g. by expanding a comment thread).
  • Changed text selection code to be a bit more browser-independent.
  • Added the jQuery frame from the SE keyboard shortcuts script.

Bugs:

  • Sometimes a button will be displayed permanently.
share|improve this question
    
Has anyone successfully used this in Google-Chrome on MacOSX or Linux? –  halirutan Nov 12 '12 at 16:09
    
@halirutan: Text selection unfortunately is a bit browser dependent, i changed the code to alleviate that but i did not expect chrome to behave differently in the first place so i do not know if this will change anything for you... –  H.B. Nov 12 '12 at 19:35
    
Unfortunately it does not help. When I have time I may try to read JavaScript ;-) –  halirutan Nov 12 '12 at 20:13
add comment

1 Answer 1

Foreword: I have absolutely no idea what I did.

The above script did not work in Chrome. Therefore, I read through some documentation about user-scripts and found that Chrome does not support unsafeWindow. Digging further, I found this answer where @tghw describes how to mimic the behavior. Combining your selector with the approach in the answer gives a script which seems to work in Chrome.

It would be very nice, if you could look over the code and bring it in a clean form.

// ==UserScript==
// @name         Select Code Block Buttons
// @namespace    stack
// @match        http://stackoverflow.com/*
// @match        http://mathematica.stackexchange.com/*
// ==/UserScript==

function addJQuery(callback) {
    var script = document.createElement("script");
    script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js");
    script.addEventListener('load', function() {
        var script = document.createElement("script");
        script.textContent = "(" + callback.toString() + ")();";
        document.body.appendChild(script);
    }, false);
    document.body.appendChild(script);
}

function main()
{

    $(document).ready(addButtons);

    function selectText(element)
    {
        var doc = document;
        if (doc.body.createTextRange)
        {
            var range = doc.body.createTextRange();
            range.moveToElementText(element);
            range.select();
        } else if (window.getSelection)
        {
            var selection = window.getSelection();
            var range = doc.createRange();
            range.selectNodeContents(element);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    }

    function addButtons()
    {
        $("pre").each(function (i, codeBlock)
        {
            var qContainer = $("<div></div>");
            var id = "select-button-" + i;
            $(codeBlock).replaceWith(qContainer);
            qContainer.append(codeBlock);

            qContainer.mouseenter(function ()
            {
                var qButton = $('<div style="position: absolute; opacity: 0; display: inline; cursor: pointer;' +
                                 'background-color: #000; color: #fff; font-size: 12pt; padding: 3px;">' +
                                 'Select</div>');
                qButton.attr("id", id);
                qContainer.append(qButton);
                var left = $(codeBlock).offset().left + $(codeBlock).width() - qButton.width();
                var top = $(codeBlock).offset().top;
                qButton.css("left", left);
                qButton.css("top", top);
                qButton.click(function ()
                {
                    selectText(codeBlock);
                });
                qButton.stop(true, true).animate({ opacity: '+=0.6' });
            });
            qContainer.mouseleave(function ()
            {
                $("#" + id).stop(true, true).animate({ opacity: '-=0.6' }, function () { $("#" + id).remove(); });
            });
        });
    }
}

// load jQuery and execute the main function
addJQuery(main);

Update

As I see now, the Official Keyboard Shortcut Script uses a similar technique. This is maybe a better template how to make it work in both, Chrome and Firefox.

share|improve this answer
    
Thanks for debugging this. I now added the code from the SE keyboard shortcuts. If you want you can test it to see if that also works for you... –  H.B. Nov 13 '12 at 18:11
    
@H.B. Yes, it works. Thanks. –  halirutan Nov 14 '12 at 22:16
add comment

You must log in to answer this question.

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