2 * Plugin that automatically truncates the plain text contents of an element and adds an ellipsis
6 // Cache ellipsed substrings for every string-width combination
8 // Use a seperate cache when match highlighting is enabled
9 var matchTextCache = { };
11 $.fn.autoEllipsis = function( options ) {
19 $(this).each( function() {
21 if ( options.restoreText ) {
22 if ( !$el.data( 'autoEllipsis.originalText' ) ) {
23 $el.data( 'autoEllipsis.originalText', $el.text() );
25 $el.text( $el.data( 'autoEllipsis.originalText' ) );
29 // container element - used for measuring against
31 // trimmable text element - only the text within this element will be trimmed
32 var $trimmableText = null;
33 // protected text element - the width of this element is counted, but next is never trimmed from it
34 var $protectedText = null;
36 if ( options.hasSpan ) {
37 $trimmableText = $el.children( options.selector );
39 $trimmableText = $( '<span />' )
40 .css( 'whiteSpace', 'nowrap' )
44 .append( $trimmableText );
47 var text = $container.text();
48 var trimmableText = $trimmableText.text();
49 var w = $container.width();
50 var pw = $protectedText ? $protectedText.width() : 0;
52 if ( !( text in cache ) ) {
55 if ( options.matchText && !( text in matchTextCache ) ) {
56 matchTextCache[text] = {};
58 if ( options.matchText && !( options.matchText in matchTextCache[text] ) ) {
59 matchTextCache[text][options.matchText] = {};
61 if ( !options.matchText && w in cache[text] ) {
62 $container.html( cache[text][w] );
63 if ( options.tooltip ) {
64 $container.attr( 'title', text );
68 if( options.matchText && options.matchText in matchTextCache[text] && w in matchTextCache[text][options.matchText] ) {
69 $container.html( matchTextCache[text][options.matchText][w] );
70 if ( options.tooltip ) {
71 $container.attr( 'title', text );
75 if ( $trimmableText.width() + pw > w ) {
76 switch ( options.position ) {
78 // Use binary search-like technique for efficiency
79 var l = 0, r = trimmableText.length;
81 var m = Math.ceil( ( l + r ) / 2 );
82 $trimmableText.text( trimmableText.substr( 0, m ) + '...' );
83 if ( $trimmableText.width() + pw > w ) {
90 $trimmableText.text( trimmableText.substr( 0, l ) + '...' );
93 // TODO: Use binary search like for 'right'
94 var i = [Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 )];
95 var side = 1; // Begin with making the end shorter
96 while ( $trimmableText.outerWidth() + pw > w && i[0] > 0 ) {
97 $trimmableText.text( trimmableText.substr( 0, i[0] ) + '...' + trimmableText.substr( i[1] ) );
98 // Alternate between trimming the end and begining
100 // Make the begining shorter
104 // Make the end shorter
111 // TODO: Use binary search like for 'right'
113 while ( $trimmableText.outerWidth() + pw > w && r < trimmableText.length ) {
114 $trimmableText.text( '...' + trimmableText.substr( r ) );
120 if ( options.tooltip ) {
121 $container.attr( 'title', text );
123 if ( options.matchText ) {
124 $container.highlightText( options.matchText );
125 matchTextCache[text][options.matchText][w] = $container.html();
127 cache[text][w] = $container.html();