2 * @class jQuery.plugin.autoEllipsis
7 // Cache ellipsed substrings for every string-width-position combination
10 // Use a separate cache when match highlighting is enabled
14 * Automatically truncate the plain text contents of an element and add an ellipsis
16 * @param {Object} options
17 * @param {'center'|'left'|'right'} [options.position='center'] Where to remove text.
18 * @param {boolean} [options.tooltip=false] Whether to show a tooltip with the remainder
20 * @param {boolean} [options.restoreText=false] Whether to save the text for restoring
22 * @param {boolean} [options.hasSpan=false] Whether the element is already a container,
23 * or if the library should create a new container for it.
24 * @param {string|null} [options.matchText=null] Text to highlight, e.g. search terms.
28 $.fn
.autoEllipsis = function ( options
) {
37 return this.each( function () {
39 text
, trimmableText
, w
, pw
,
41 // container element - used for measuring against
42 $container
= $( this );
44 if ( options
.restoreText
) {
45 if ( !$container
.data( 'autoEllipsis.originalText' ) ) {
46 $container
.data( 'autoEllipsis.originalText', $container
.text() );
48 $container
.text( $container
.data( 'autoEllipsis.originalText' ) );
52 // trimmable text element - only the text within this element will be trimmed
53 if ( options
.hasSpan
) {
54 $trimmableText
= $container
.children( options
.selector
);
56 $trimmableText
= $( '<span>' )
57 .css( 'whiteSpace', 'nowrap' )
58 .text( $container
.text() );
61 .append( $trimmableText
);
64 text
= $container
.text();
65 trimmableText
= $trimmableText
.text();
66 w
= $container
.width();
70 if ( options
.matchText
) {
71 if ( !( text
in matchTextCache
) ) {
72 matchTextCache
[text
] = {};
74 if ( !( options
.matchText
in matchTextCache
[text
] ) ) {
75 matchTextCache
[text
][options
.matchText
] = {};
77 if ( !( w
in matchTextCache
[text
][options
.matchText
] ) ) {
78 matchTextCache
[text
][options
.matchText
][w
] = {};
80 if ( options
.position
in matchTextCache
[text
][options
.matchText
][w
] ) {
81 $container
.html( matchTextCache
[text
][options
.matchText
][w
][options
.position
] );
82 if ( options
.tooltip
) {
83 $container
.attr( 'title', text
);
88 if ( !( text
in cache
) ) {
91 if ( !( w
in cache
[text
] ) ) {
94 if ( options
.position
in cache
[text
][w
] ) {
95 $container
.html( cache
[text
][w
][options
.position
] );
96 if ( options
.tooltip
) {
97 $container
.attr( 'title', text
);
103 if ( $trimmableText
.width() + pw
> w
) {
104 switch ( options
.position
) {
106 // Use binary search-like technique for efficiency
108 r
= trimmableText
.length
;
110 m
= Math
.ceil( ( l
+ r
) / 2 );
111 $trimmableText
.text( trimmableText
.substr( 0, m
) + '...' );
112 if ( $trimmableText
.width() + pw
> w
) {
119 $trimmableText
.text( trimmableText
.substr( 0, l
) + '...' );
122 // TODO: Use binary search like for 'right'
123 i
= [Math
.round( trimmableText
.length
/ 2 ), Math
.round( trimmableText
.length
/ 2 )];
124 // Begin with making the end shorter
126 while ( $trimmableText
.outerWidth() + pw
> w
&& i
[0] > 0 ) {
127 $trimmableText
.text( trimmableText
.substr( 0, i
[0] ) + '...' + trimmableText
.substr( i
[1] ) );
128 // Alternate between trimming the end and begining
130 // Make the begining shorter
134 // Make the end shorter
141 // TODO: Use binary search like for 'right'
143 while ( $trimmableText
.outerWidth() + pw
> w
&& r
< trimmableText
.length
) {
144 $trimmableText
.text( '...' + trimmableText
.substr( r
) );
150 if ( options
.tooltip
) {
151 $container
.attr( 'title', text
);
153 if ( options
.matchText
) {
154 $container
.highlightText( options
.matchText
);
155 matchTextCache
[text
][options
.matchText
][w
][options
.position
] = $container
.html();
157 cache
[text
][w
][options
.position
] = $container
.html();
165 * @mixins jQuery.plugin.autoEllipsis