13
\$\begingroup\$

The following code will add to each code block a 'Select Code' button that will select the code belonging to that block. Please review for maintainability.

In order to use this, visit http://codereviewcommunity.github.io/CodeReviewBookmarklet/

javascript: if ($('button').length === 0) { 
  /* Stack Exchange does not do buttons, this does */
  $(".prettyprint").each( function()
  { 
    /* Thank you http://stackoverflow.com/a/2838358/7602 */
    function selectCode(el, win) 
    {
      win = win || window;
      var doc = win.document, sel, range;
      if (win.getSelection && doc.createRange) 
      {
        sel = win.getSelection();
        range = doc.createRange();
        range.selectNodeContents(el);
        sel.removeAllRanges();
        sel.addRange(range);
      } 
      else if (doc.body.createTextRange) 
      {
        range = doc.body.createTextRange();
        range.moveToElementText(el);
        range.select();
      }
    }

    var buttonText  = 'Select Code',
        length      = buttonText.length,
        codeBlock   = this,
        $link       = $('<button type="button">' + buttonText + '</button><br>').click(function()
        {
          console.log( $(codeBlock).text().substring( length ) );
          selectCode(codeBlock);
        });
    $(codeBlock).prepend( $link );
  });
}

I have tested this on FF and Chrome and it works for me.

\$\endgroup\$
7
  • \$\begingroup\$ Works on Safari 7. \$\endgroup\$ Commented Dec 30, 2013 at 23:13
  • \$\begingroup\$ How do you test this with Chrome? \$\endgroup\$
    – Jamal
    Commented Dec 30, 2013 at 23:25
  • 1
    \$\begingroup\$ Select the test, then mouse-down for half a second, and then drag the code into the bookmark-bar. \$\endgroup\$
    – konijn
    Commented Dec 30, 2013 at 23:50
  • \$\begingroup\$ Nice! You could consider putting the updated code below the original, while clearly marking it as such. \$\endgroup\$
    – Jamal
    Commented Dec 30, 2013 at 23:53
  • \$\begingroup\$ @Jamal I don't like the button size with before, I will have to play with it a bit. \$\endgroup\$
    – konijn
    Commented Dec 31, 2013 at 0:21

2 Answers 2

10
\$\begingroup\$

You inject the button using jQuery.prepend(), which inserts the button as the first child of the .prettyprint code block. Therefore, when the bookmarklet is invoked, and it selects the contents of the code block, the "Select Code" button is inadvertently included in the selection. I recommend using jQuery.before() instead.

\$\endgroup\$
2
  • \$\begingroup\$ You are right, will fix. On FF, the text of the button does not actually make it into the clipboard. \$\endgroup\$
    – konijn
    Commented Dec 30, 2013 at 23:50
  • 1
    \$\begingroup\$ This works on Chrome. \$\endgroup\$
    – Jamal
    Commented Dec 31, 2013 at 0:09
7
+50
\$\begingroup\$

Since StackExchange can refresh page contents dynamically, the following sequence of events is possible:

  1. Page contains some code block(s).
  2. Bookmarklet is invoked, adding the button to existing code block(s).
  3. Page contents are updated, for example, with a new answer that contains a new code block.
  4. Bookmarklet is invoked again, but it refuses add a Select Code button to the new code block.

Therefore, I suggest that the overall structure be changed such that it can be invoked again after a content update. Here is one approach (assuming that you also take my previous advice to use jQuery.before()):

javascript:$("pre.prettyprint").not("button + *").each(function() { 
    …

    var buttonText  = 'Select Code',
        length      = buttonText.length,
        codeBlock   = this,
        $link       = $('<button type="button">' + buttonText + '</button>').click(…);
    $(codeBlock).before( $link );
  });

I've changed the selector $(".prettyprint") to $("pre.prettyprint") because class-only selectors are reputed to be slower.

For the .not("button + *") next-sibling filter to work, the button must not be inserted with a <br> afterwards. The <br> is unnecessary anyway, since <pre> is a block element.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.