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 ( ! $this.data( 'autoEllipsis.originalText' ) ) {
23 $this.data( 'autoEllipsis.originalText', $this.text() );
25 $this.text( $this.data( 'autoEllipsis.originalText' ) );
29 // container element - used for measuring against
30 var $container
= $this;
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
= $this.children( options
.selector
);
39 $trimmableText
= $( '<span />' )
40 .css( 'whiteSpace', 'nowrap' )
41 .text( $this.text() );
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
);
67 if( options
.matchText
&& options
.matchText
in matchTextCache
[text
] && w
in matchTextCache
[text
][options
.matchText
] ) {
68 $container
.html( matchTextCache
[text
][options
.matchText
][w
] );
69 if ( options
.tooltip
)
70 $container
.attr( 'title', text
);
73 if ( $trimmableText
.width() + pw
> w
) {
74 switch ( options
.position
) {
76 // Use binary search-like technique for efficiency
77 var l
= 0, r
= trimmableText
.length
;
79 var m
= Math
.ceil( ( l
+ r
) / 2 );
80 $trimmableText
.text( trimmableText
.substr( 0, m
) + '...' );
81 if ( $trimmableText
.width() + pw
> w
) {
88 $trimmableText
.text( trimmableText
.substr( 0, l
) + '...' );
91 // TODO: Use binary search like for 'right'
92 var i
= [Math
.round( trimmableText
.length
/ 2 ), Math
.round( trimmableText
.length
/ 2 )];
93 var side
= 1; // Begin with making the end shorter
94 while ( $trimmableText
.outerWidth() + pw
> w
&& i
[0] > 0 ) {
95 $trimmableText
.text( trimmableText
.substr( 0, i
[0] ) + '...' + trimmableText
.substr( i
[1] ) );
96 // Alternate between trimming the end and begining
98 // Make the begining shorter
102 // Make the end shorter
109 // TODO: Use binary search like for 'right'
111 while ( $trimmableText
.outerWidth() + pw
> w
&& r
< trimmableText
.length
) {
112 $trimmableText
.text( '...' + trimmableText
.substr( r
) );
118 if ( options
.tooltip
) {
119 $container
.attr( 'title', text
);
121 if ( options
.matchText
) {
122 $container
.highlightText( options
.matchText
);
123 matchTextCache
[text
][options
.matchText
][w
] = $container
.html();
125 cache
[text
][w
] = $container
.html();