1(function($) { 2 3 var trailing_whitespace = true; 4 5 $.fn.truncate = function(options) { 6 7 var opts = $.extend({}, $.fn.truncate.defaults, options); 8 9 $(this).each(function() { 10 11 var content_length = $.trim(squeeze($(this).text())).length; 12 if (content_length <= opts.max_length) 13 return; // bail early if not overlong 14 15 var actual_max_length = opts.max_length - opts.more.length - 3; // 3 for " ()" 16 var truncated_node = recursivelyTruncate(this, actual_max_length); 17 var full_node = $(this).hide(); 18 19 truncated_node.insertAfter(full_node); 20 21 findNodeForMore(truncated_node).append('...<a href="#show more content">'+opts.more+'</a>'); 22 findNodeForLess(full_node).append('<a href="#show less content">'+opts.less+'</a>'); 23 24 truncated_node.find('a:last').click(function() { 25 truncated_node.hide(); full_node.show(); return false; 26 }); 27 full_node.find('a:last').click(function() { 28 truncated_node.show(); full_node.hide(); return false; 29 }); 30 31 }); 32 } 33 34 // Note that the " (â¦more)" bit counts towards the max length â so a max 35 // length of 10 would truncate "1234567890" to "12 (â¦more)". 36 $.fn.truncate.defaults = { 37 max_length: 100, 38 more: 'â¦more', 39 less: 'less' 40 }; 41 42 function recursivelyTruncate(node, max_length) { 43 return (node.nodeType == 3) ? truncateText(node, max_length) : truncateNode(node, max_length); 44 } 45 46 function truncateNode(node, max_length) { 47 var node = $(node); 48 var new_node = node.clone().empty(); 49 var truncatedChild; 50 node.contents().each(function() { 51 var remaining_length = max_length - new_node.text().length; 52 if (remaining_length == 0) return; // breaks the loop 53 truncatedChild = recursivelyTruncate(this, remaining_length); 54 if (truncatedChild) new_node.append(truncatedChild); 55 }); 56 return new_node; 57 } 58 59 function truncateText(node, max_length) { 60 var text = squeeze(node.data); 61 if (trailing_whitespace) // remove initial whitespace if last text 62 text = text.replace(/^ /, ''); // node had trailing whitespace. 63 trailing_whitespace = !!text.match(/ $/); 64 var text = text.slice(0, max_length); 65 // Ensure HTML entities are encoded 66 // http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb 67 text = $('<div/>').text(text).html(); 68 return text; 69 } 70 71 // Collapses a sequence of whitespace into a single space. 72 function squeeze(string) { 73 return string.replace(/\s+/g, ' '); 74 } 75 76 // Finds the last, innermost block-level element 77 function findNodeForMore(node) { 78 var $node = $(node); 79 var last_child = $node.children(":last"); 80 if (!last_child) return node; 81 var display = last_child.css('display'); 82 if (!display || display=='inline') return $node; 83 return findNodeForMore(last_child); 84 }; 85 86 // Finds the last child if it's a p; otherwise the parent 87 function findNodeForLess(node) { 88 var $node = $(node); 89 var last_child = $node.children(":last"); 90 if (last_child && last_child.is('p')) return last_child; 91 return node; 92 }; 93 94})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.