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