152 lines
6.3 KiB
JavaScript
152 lines
6.3 KiB
JavaScript
/*
|
|
* jQuery Shorten plugin 1.1.0
|
|
*
|
|
* Copyright (c) 2014 Viral Patel
|
|
* http://viralpatel.net
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*/
|
|
|
|
/*
|
|
** updated by Jeff Richardson
|
|
** Updated to use strict,
|
|
** IE 7 has a "bug" It is returning undefined when trying to reference string characters in this format
|
|
** content[i]. IE 7 allows content.charAt(i) This works fine in all modern browsers.
|
|
** I've also added brackets where they weren't added just for readability (mostly for me).
|
|
*/
|
|
|
|
(function($) {
|
|
$.fn.shorten = function(settings) {
|
|
"use strict";
|
|
|
|
var config = {
|
|
showChars: 100,
|
|
minHideChars: 10,
|
|
ellipsesText: "...",
|
|
moreText: "more",
|
|
lessText: "less",
|
|
onLess: function() {},
|
|
onMore: function() {},
|
|
errMsg: null,
|
|
force: false
|
|
};
|
|
|
|
if (settings) {
|
|
$.extend(config, settings);
|
|
}
|
|
|
|
if ($(this).data('jquery.shorten') && !config.force) {
|
|
return false;
|
|
}
|
|
$(this).data('jquery.shorten', true);
|
|
|
|
$(document).off("click", '.morelink');
|
|
|
|
$(document).on({
|
|
click: function() {
|
|
|
|
var $this = $(this);
|
|
if ($this.hasClass('less')) {
|
|
$this.removeClass('less');
|
|
$this.html(config.moreText);
|
|
$this.parent().prev().animate({'height':'0'+'%'}, function () { $this.parent().prev().prev().show(); }).hide('fast', function() {
|
|
config.onLess();
|
|
});
|
|
|
|
} else {
|
|
$this.addClass('less');
|
|
$this.html(config.lessText);
|
|
$this.parent().prev().animate({'height':'100'+'%'}, function () { $this.parent().prev().prev().hide(); }).show('fast', function() {
|
|
config.onMore();
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
}, '.morelink');
|
|
|
|
return this.each(function() {
|
|
var $this = $(this);
|
|
|
|
var content = $this.html();
|
|
var contentlen = $this.text().length;
|
|
if (contentlen > config.showChars + config.minHideChars) {
|
|
var c = content.substr(0, config.showChars);
|
|
if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
|
|
{
|
|
var inTag = false; // I'm in a tag?
|
|
var bag = ''; // Put the characters to be shown here
|
|
var countChars = 0; // Current bag size
|
|
var openTags = []; // Stack for opened tags, so I can close them later
|
|
var tagName = null;
|
|
|
|
for (var i = 0, r = 0; r <= config.showChars; i++) {
|
|
if (content[i] == '<' && !inTag) {
|
|
inTag = true;
|
|
|
|
// This could be "tag" or "/tag"
|
|
tagName = content.substring(i + 1, content.indexOf('>', i));
|
|
|
|
// If its a closing tag
|
|
if (tagName[0] == '/') {
|
|
|
|
|
|
if (tagName != '/' + openTags[0]) {
|
|
config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
|
|
} else {
|
|
openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
|
|
}
|
|
|
|
} else {
|
|
// There are some nasty tags that don't have a close tag like <br/>
|
|
if (tagName.toLowerCase() != 'br') {
|
|
openTags.unshift(tagName); // Add to start the name of the tag that opens
|
|
}
|
|
}
|
|
}
|
|
if (inTag && content[i] == '>') {
|
|
inTag = false;
|
|
}
|
|
|
|
if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
|
|
else {
|
|
r++;
|
|
if (countChars <= config.showChars) {
|
|
bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
|
|
countChars++;
|
|
} else // Now I have the characters needed
|
|
{
|
|
if (openTags.length > 0) // I have unclosed tags
|
|
{
|
|
//console.log('They were open tags');
|
|
//console.log(openTags);
|
|
for (j = 0; j < openTags.length; j++) {
|
|
//console.log('Cierro tag ' + openTags[j]);
|
|
bag += '</' + openTags[j] + '>'; // Close all tags that were opened
|
|
|
|
// 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
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
|
|
}else{
|
|
c+=config.ellipsesText;
|
|
}
|
|
|
|
var html = '<div class="shortcontent">' + c +
|
|
'</div><div class="allcontent">' + content +
|
|
'</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
|
|
|
|
$this.html(html);
|
|
$this.find(".allcontent").hide(); // Hide all text
|
|
$('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
|
|
}
|
|
});
|
|
|
|
};
|
|
|
|
})(jQuery);
|