IT Cooking

IT Stuff and Silly Shell

Spread the love

 

 

Adding the ability to Copy Text Code Blocks Without Flash, with a click from a Copy Text Button inside a Syntax highlighted Code Block, that’s real magic. Bonus: the copied code includes Rich Text Format (RTF syntax). This solution relies on Clibboard.JS, and is the easiest one to add to your site. I could make it work under two hours, so I hope this tutorial will help you make it in less!

This text will be copied onto the clipboard when you click the button below. Try it!

Look at the paste in Winword: already formatted! Magic!! 😍

Yeah, I’m still using Word 2007 in 2017… That’s another point I will explain in another post.

Rationale to Copy Text with a Button

There are two different schools for this implementation. The first I encountered relies on a pseudo Flash animation, but many browser and especially iPhones do disable Flash, and it’s not easy to implement. I’ve tried without much success. The second solution is relying on Clipboard.JS and works out of the box. No Flash, no hassle.

The idea is simple: you create your EnlighterJS code boxes in your posts, and a JS code snippet will create a Copy Text button when your visitors will hover the box, styled and placed within with another CSS snippet. I swear that’s as easy as it sounds! You can also use another syntax highlighter plugin or use it for input or textarea as well. With a small adaptation of the code box detection via JavaScript indeed.

Step by step process:

Install a Syntax Highlighter Plugin for WordPress

I describe a solution based on EnlighterJS for WordPress in another post, but you are perfectly fine with any other syntax highlighter if you update the JS a little bit.

Once you add code-blocks in your posts with EnlighterJS, it will produce some formatted output in the font-end. Let’s take an example with this code:

/* css comment */
@element ul {
...etc...

EnlighterJS will actually produce this code on your front-end:

<pre class="EnlighterJSRAW" data-enlighter-language="css" style="display: none;">
  /* css comment */
  @element ul {
  ...etc...
</pre>

<div class="EnlighterJSWrapper enlighterEnlighterJSWrapper">
  <ul class="hoverEnabled enlighterEnlighterJS EnlighterJS">
    <li class=" odd"><span class="co1">/* css comment */</span><span class=""></span></li>
    <li class=" even"><span class=""></span><span class="kw2">@element</span><span class=""> ul </span><span class="br0">{</span><span class=""></span></li>
    <li class=" odd"><span class="">...etc...</li>
  </ul>
  <pre style="display: none;">
  /* css comment */
  @element ul {
  ...etc...
  </pre>
  <div class="EnlighterJSToolbar">
    <a class="EnlighterJSRawButton" title="Toggle RAW Code"></a>
    <span class="clear"></span>
  </div>
</div>

In this example, your block-code contains 3 lines of CSS code.

EnlighterJS wrap your code with a hidden <pre> and just after, inside another <pre> within a <div>. I’m not sure why there are two <pre> generated, but anyway, we will insert a Copy button in the <div> with the class .EnlighterJSWrapper.

Your mileage may vary with Highlight.js or Crayon, so the JS Snippet I provide will have to be updated regarding the situation.

Add the Clipboard.JS CDN to Copy Code

You need the Clipboard.JS script in the footer, this can be done with another great plugin of mine: WP CDNjs reborn, a fork from WP cdnjs (looks abandoned for 2 years):

Result:

Install Custom CSS & JS plugin for WordPress

Now you need to add CSS and JS snippets to your site. The best WordPress plugin around is Custom CSS & JS plugin for WordPress. Let’s add the two snippets bellow:

Create a JS snippet

  • This will create a Copy Text button defined by <div class="btn-clipboard">
  • Then it embeds the button within the <div> from EnlighterJS, inserted as the first element.
  • A jQuery event will trigger a new Clipboard.JS object on click, and look for the nextElementSibling from the trigger.
  • The next element is indeed the <ul class="hoverEnabled enlighterEnlighterJS EnlighterJS"> containing the highlighted code from EnlighterJS, that will be passed to the clipboard object.

Some fancy stuff have been added such as show/hide on hovering and changing the text from the button to notify the user that it worked.

var copyButton = '<div class="btn-clipboard" title="" data-original-title="Copy to clipboard">Copy</div>';
$( document ).ready(function() {
  $(document).on('mouseenter', 'div.EnlighterJSWrapper', function(){
    if(!$(this).has(".btn-clipboard").length) $(this).prepend($(copyButton));
    $(this).children('.btn-clipboard').show();
  }).on('mouseleave', 'div.EnlighterJSWrapper', function () {
    $(this).children('.btn-clipboard').hide();
  });
  
  // Run Clipboard
  var copyCode = new Clipboard('.btn-clipboard', {
    target: function(trigger) {
      return trigger.nextElementSibling;
    }
  });
  
  // On success:
  // - Change the "Copy" text to "Copied".
  // - Swap it to "Copy" in 2s.
  // - Lead user to the "contenteditable" area with Velocity scroll.
  
  copyCode.on('success', function(event) {
    event.clearSelection();
    event.trigger.textContent = 'Copied';
    window.setTimeout(function() {
      event.trigger.textContent = 'Copy';
    }, 2000);

    /* $.Velocity(pasteContent, 'scroll', { 
      duration: 1000 
    }); */
  });

  // On error (Safari):
  // - Change the  "Press Ctrl+C to copy"
  // - Swap it to "Copy" in 2s.
  copyCode.on('error', function(event) { 
    event.trigger.textContent = 'Press "Ctrl + C" to copy';
    window.setTimeout(function() {
      event.trigger.textContent = 'Copy';
    }, 5000);
  });
  
});
  • Where on page: Footer
  • Where in site: In Frontend

Create a CSS snippet

This will place the floating Copy Text button inside the <div class="EnlighterJSWrapper>, at the bottom right.

.bd-clipboard {
    display: block;
    /* position: relative; */
    float: right;
}
.btn-clipboard {
    position: absolute;
    bottom: 3rem;
    right: 1rem;
    z-index: 10;
    display: block;
    padding: .25rem .5rem;
    /* font-size: 75%; */
    color: #818a91;
    cursor: pointer;
    background-color: transparent;
    border-radius: .25rem;
}
.btn-clipboard:hover {
    color: #fff;
    background-color: #027de7;
}
  • Where on page: Footer
  • Where in site: In Frontend

Wrapping up

It works, out of the box, with no additional action from you. The Copy Text buttons are generated on the fly, by hovering the syntax highlighted code-blocks auto-magically. Your site is now interactive and light-speed fast. Say thanks in the comments!


Spread the love
Posted In: jQuery, WordPress, CSS Tags: , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *