2

I need to show the code of some Divs in page. Div should be cloned into pre tag with proper spacing and identation and should work in ie8.

I'm a starter so don't really know if i'm doing it correct way, so far i wrote this

Html

//create button after div
    $("<div class='btn'>click to show code</div>").insertAfter(".content-wrapper");

    //create pre wrapper after button
    $("<pre></pre>").insertAfter(".btn");

    //hide the pre so can slidetoggle later
    $("pre").hide();
    
    $(".btn").one("click", function() {
    
      var cloned = $(this).prev().clone();
      var code = $(cloned).html().replace(/</g, "&lt;").replace(/>/g, "&gt;");
      $(this).next().append(code);
    
    });
    
    $(".btn").click(function() {
      $(this).next().slideToggle("fast", function() {
      });
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="wrapper-all">
            <div class="content-wrapper">
                <div class="example-div">
                    <span>lorem ipsum first</span>
                </div>
            </div>
        </div>

        <div class="wrapper-all">
            <div class="content-wrapper">
                <div class="example-div">
                    <span>lorem ipsum second</span>
                </div>
            </div>
        </div>

jsfiddle

It dynamically adds, button and pre after the .content-wrapper divs which can be slide toggled.

ie8 completeley ignores whitespaces, and in chrome,firefox some unwanted whitespaces appearing, the outputed code should respect the identation of the original divs, but remove the spaces from left and code should start from zero whitespace to the left.

stackov
  • 71
  • 12
  • possible duplicate of [How to preserve whitespace indentation of text enclosed in HTML
     tags excluding the current indentation level of the 
     tag in the document?](http://stackoverflow.com/questions/4631646/how-to-preserve-whitespace-indentation-of-text-enclosed-in-html-pre-tags-exclu)
    – showdev Dec 12 '14 at 20:16
  • thanks ! that is just what i was searching for, how can i implement it to my existing code ? – stackov Dec 12 '14 at 21:01

1 Answers1

0

I had some success with the following method, loosely based on other answers here. It seems a little "brute-forcey" and may be brittle depending on how well your HTML is formatted.

Basically, it splits the lines of HTML content into an array. It determines the number of spaces at the beginning of the first line and removes that number of spaces from all lines. This resets indentation so that the first line is not indented and subsequent lines are only indented relative to the first line.

So, if the first line is indented by 15 spaces and the second line is indented by 20 spaces, the first line will not be indented and the second line will be indented by 5 spaces (20-15).

$(".btn").one("click", function () {

    var cloned = $(this).prev('.content-wrapper').clone(),

        // Get the code from the clone and split it by new lines.
        // Then filter the array to remove blank lines.
        code = $(cloned).html().split("\n").filter(function (n) {
            return (n.replace(/\s+$/, '') != '');
        }),

        // Determine the number of spaces on the left of the first line
        spacesOnLeft = code[0].match(/^ */)[0].length;

    // loop through each line, removing unnecessary indentation spaces.
    // Append the line to the output area
    for (i in code) {
        var $output = $(this).next(),
            existing_text=$output.text(),
            new_text=code[i].substring(spacesOnLeft);
        $output.text(existing_text + new_text + '\n');
    }

});

Test below:

//create button after div
$("<div class='btn'>show code</div>").insertAfter(".content-wrapper");
//create pre wrapper after button
$("<pre></pre>").insertAfter(".btn");
//hide the pre so can slidetoggle later
$("pre").hide();

$(".btn").one("click", function() {

  var cloned = $(this).prev('.content-wrapper').clone(),
    code = $(cloned).html().split("\n").filter(function(n) {
      return (n.replace(/\s+$/, '') != '');
    }),
    spacesOnLeft = code[0].match(/^ */)[0].length;

  for (i in code) {
      var $output = $(this).next(),
          existing_text=$output.text(),
          new_text=code[i].substring(spacesOnLeft);
      $output.text(existing_text + new_text + '\n');
  }

});

$(".btn").click(function() {
  $(this).next().slideToggle("fast", function() {});
});
.wrapper-all {
  margin-bottom: 40px;
}
.example-div {
  padding: 40px;
  background-color: #ecf0f1;
  text-align: center;
}
.btn {
  padding: 8px 20px;
  background-color: #1abc9c;
  color: white;
  width: auto;
  cursor: pointer;
  margin: 0 auto;
  text-align: center;
  text-transform: uppercase;
  transition: background-color 0.16s ease-in-out;
}
.btn:hover {
  background-color: #16a085;
}
pre {
  background-color: #34495e;
  color: white;
  margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="wrapper-all">
    <div class="content-wrapper">
        <div class="example-div">
            <span>lorem ipsum first</span>
        </div>
    </div>
</div>
<div class="wrapper-all">
    <div class="content-wrapper">
        <div class="example-div">
            <span>lorem ipsum second</span>
        </div>
    </div>
</div>
Community
  • 1
  • 1
showdev
  • 28,454
  • 37
  • 55
  • 73
  • thanks, this is great, works great on firefox and chrome, but can't work in ie8, gives error " Object doesn't support this property or method Line ... " which is this code on that line for (i in code) { – stackov Dec 12 '14 at 22:24
  • I'm not exactly sure, but I have read [here](http://stackoverflow.com/questions/4824207/javascript-for-in-looping-over-arguments-ie-for-arg-in-arguments-does-not-wor) and [there](http://stackoverflow.com/questions/412447/for-each-javascript-support-in-ie) that IE8 does not support "for in" syntax. Not sure if that's accurate. But in any case, you can do the same thing with something like `for (var i = 0, len = code.length; i < len; i++) {` or by using jQuery's [`each()`](http://api.jquery.com/jquery.each/). See if that helps. – showdev Dec 12 '14 at 22:34
  • Any luck with that? I'm curious about IE8. – showdev Dec 12 '14 at 23:54
  • i've just tried the for (var i = 0, len = code.length; i < len; i++) { but had no luck, i'm a beginner with js , can you help me convert it to jquery each() ? maybe jquery version can work. Thanks ! – stackov Dec 13 '14 at 00:14
  • Here's an [example using a for loop](http://jsfiddle.net/sLfugy8k/). Here's an [example using jQuery each()](http://jsfiddle.net/sLfugy8k/1/). – showdev Dec 15 '14 at 17:05
  • Thanks, still gives error in ie8, but no problem, works on mobile and desktop firefox,chrome. I can drop support for ie8, it was for documentation of my project. Thanks again it works great! – stackov Dec 17 '14 at 22:19