View difference between Paste ID: svRPehJJ and L03VXeyd
SHOW: | | - or go back to the newest paste.
1
;(function($) {
2
3
  $.fn.shorten = function(settings) {
4
  
5
   var config = $.extend( {
6
     showChars : 100,
7
     ellipsesText : "...",
8
     moreText : "more",
9
     lessText : "less"
10
    }, settings);
11
  
12
    $('.morelink').live('click', function() {
13
      var $this = $(this);
14
      
15
      // Toggle del nombre del link
16
      if ($this.hasClass('less')) { // clic en more para mostrar less
17
        
18
        $this.removeClass('less');
19
        $this.html(config.moreText);
20
        
21
        // muestro shorcontent y escondo allcontent
22
        $this.parent().prev().prev().show(); // shortcontent
23
        $this.parent().prev().hide(); // allcontent
24
        
25
      } else { // click en less para mostrar more
26
        
27
        $this.addClass('less');
28
        $this.html(config.lessText);
29
        
30
        $this.parent().prev().prev().hide(); // shortcontent
31
        $this.parent().prev().show(); // allcontent
32
      }
33
      
34
      return false;
35-
      //$this.parent().prev().css('border', '2px solid blue'); // el lnk no tiene prev
35+
36-
      //$this.parent().prev().prev().css('border', '2px solid orange'); // shortcontent
36+
37
    return this.each(function() {
38
      var $this = $(this);
39
  
40
      var content = $this.html();
41
      if (content.length > config.showChars) {
42
        var c = content.substr(0, config.showChars);
43
        if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
44
        {
45
          var inTag = false; // I'm in a tag?
46
          var bag = ''; // Put the characters to be shown here
47
          var countChars = 0; // Current bag size
48-
        if (c.indexOf('<') >= 0) // Si hay HTML tengo que tener cuidado de no cortarlo!
48+
          var openTags = []; // Stack for opened tags, so I can close them later
49
          
50-
          //var index = 0; // Indice de recorrida del string
50+
51-
          var inTag = false; // Indicador de que el indice actual esta dentro de una tag
51+
52-
          var bag = ''; // String donde voy a cumulando los caracteres que se muestran
52+
53-
          // Recorro el texto, cortando lo que no es tag hasta alcanzar el largo deseado, y asegurar de que no hay una tag abierta cordada
53+
54-
          var countChars = 0; // Caracteres del string resultante
54+
55-
          var openTags = []; // sirve como stack para poner y sacar tags, si termina no vacio, hay tags sin cerrar
55+
56
              // This could be "tag" or "/tag"
57
              tagName = content.substring(i+1, content.indexOf('>', i));
58
              
59
              // If its a closing tag
60
              if (tagName[0] == '/')
61
              {
62
                if (tagName != '/'+openTags[0]) console.log('ERROR en HTML: el tope del stack debe ser la tag que cierra');
63-
              // Cuidado, puede ser un cierre de tag y le pone /tag
63+
64
                  openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
65
              }
66-
              // Si es una tag que cierra otra, la que cierra deberia estar arriba en el stack (verifico por las dudas)
66+
67
              {
68
                // There are some nasty tags that don't have a close tag like <br/>
69
                if (tagName.toLowerCase() != 'br')
70
                  openTags.unshift( tagName );// Agrega al inicio el nombre de la tag que abre
71-
                  openTags.shift(); // Saca el tope del stack (tag que acabo de cerrar) 
71+
72
            }
73
            if (inTag && content[i] == '>')
74
            {
75-
                // Evita poner en el stack la tag que no se cierra, TODO: pueden haber otras...
75+
76
            }
77
            
78
            if (inTag) bag += content[i]; // Add tag name chars to the result
79
            else
80
            {
81-
              // TODO: asegurarme de que la tag esta cerrada cuando termine de cortar el texto
81+
82
              {
83
                bag += content[i];
84
                countChars ++;
85
              }
86-
              //bag += content[i]; // Agrega ultimo > para cerrar la tag en la que estaba '<tag'+'>'
86+
87
              {
88
                if (openTags.length > 0) // Tengo tags sin cerrar
89-
            if (inTag) bag += content[i]; // Agrego toda la tag
89+
90
                  console.log('Quedaron tags abiertas');
91
                  console.log(openTags);
92-
              // Si faltan caracteres para poner en la bag
92+
93
                  {
94
                    console.log('Cierro tag '+ openTags[j]);
95
                    bag += '</'+ openTags[j] +'>'; // Cierro todas las tags que quedaron abiertas
96
97
                    // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags
98
                  }
99
                  break;
100
                }
101
              }
102
            }
103
          }
104
          c = bag;
105
        }
106
        
107
        var html = '<span class="shortcontent">' + c + '&nbsp;' + config.ellipsesText +
108-
                    
108+
109-
                    // FIXED arriba:
109+
110-
                    // tags como <br> pueden abrirse y no tener cierre, o sea que quedan en el stack pero si las cierro no queda un HTML valido porque no hay apertura.
110+
111-
                    
111+
112-
                    // Podria sacar la tag cerrada del stack para que salga un stack vacio.
112+
113
      }
114-
                  break; // Del for por los caracteres
114+
115
  };
116
})(jQuery);