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 + ' ' + 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); |