/* * jquery dotdotdot 1.7.2 * * copyright (c) fred heusschen * www.frebsite.nl * * plugin website: * dotdotdot.frebsite.nl * * licensed under the mit license. * http://en.wikipedia.org/wiki/mit_license */ (function( $, undef ) { if ( $.fn.dotdotdot ) { return; } $.fn.dotdotdot = function( o ) { if ( this.length == 0 ) { $.fn.dotdotdot.debug( 'no element found for "' + this.selector + '".' ); return this; } if ( this.length > 1 ) { return this.each( function() { $(this).dotdotdot( o ); } ); } var $dot = this; if ( $dot.data( 'dotdotdot' ) ) { $dot.trigger( 'destroy.dot' ); } $dot.data( 'dotdotdot-style', $dot.attr( 'style' ) || '' ); $dot.css( 'word-wrap', 'break-word' ); if ($dot.css( 'white-space' ) === 'nowrap') { $dot.css( 'white-space', 'normal' ); } $dot.bind_events = function() { $dot.bind( 'update.dot', function( e, c ) { e.preventdefault(); e.stoppropagation(); opts.maxheight = ( typeof opts.height == 'number' ) ? opts.height : gettrueinnerheight( $dot ); opts.maxheight += opts.tolerance; if ( typeof c != 'undefined' ) { if ( typeof c == 'string' || ('nodetype' in c && c.nodetype === 1) ) { c = $('
').append( c ).contents(); } if ( c instanceof $ ) { orgcontent = c; } } $inr = $dot.wrapinner( '
' ).children(); $inr.contents() .detach() .end() .append( orgcontent.clone( true ) ) .find( 'br' ) .replacewith( '
' ) .end() .css({ 'height' : 'auto', 'width' : 'auto', 'border' : 'none', 'padding' : 0, 'margin' : 0 }); var after = false, trunc = false; if ( conf.afterelement ) { after = conf.afterelement.clone( true ); after.show(); conf.afterelement.detach(); } if ( test( $inr, opts ) ) { if ( opts.wrap == 'children' ) { trunc = children( $inr, opts, after ); } else { trunc = ellipsis( $inr, $dot, $inr, opts, after ); } } $inr.replacewith( $inr.contents() ); $inr = null; if ( $.isfunction( opts.callback ) ) { opts.callback.call( $dot[ 0 ], trunc, orgcontent ); } conf.istruncated = trunc; return trunc; } ).bind( 'istruncated.dot', function( e, fn ) { e.preventdefault(); e.stoppropagation(); if ( typeof fn == 'function' ) { fn.call( $dot[ 0 ], conf.istruncated ); } return conf.istruncated; } ).bind( 'originalcontent.dot', function( e, fn ) { e.preventdefault(); e.stoppropagation(); if ( typeof fn == 'function' ) { fn.call( $dot[ 0 ], orgcontent ); } return orgcontent; } ).bind( 'destroy.dot', function( e ) { e.preventdefault(); e.stoppropagation(); $dot.unwatch() .unbind_events() .contents() .detach() .end() .append( orgcontent ) .attr( 'style', $dot.data( 'dotdotdot-style' ) || '' ) .data( 'dotdotdot', false ); } ); return $dot; }; // /bind_events $dot.unbind_events = function() { $dot.unbind('.dot'); return $dot; }; // /unbind_events $dot.watch = function() { $dot.unwatch(); if ( opts.watch == 'window' ) { var $window = $(window), _wwidth = $window.width(), _wheight = $window.height(); $window.bind( 'resize.dot' + conf.dotid, function() { if ( _wwidth != $window.width() || _wheight != $window.height() || !opts.windowresizefix ) { _wwidth = $window.width(); _wheight = $window.height(); if ( watchint ) { clearinterval( watchint ); } watchint = settimeout( function() { $dot.trigger( 'update.dot' ); }, 100 ); } } ); } else { watchorg = getsizes( $dot ); watchint = setinterval( function() { if ( $dot.is( ':visible' ) ) { var watchnew = getsizes( $dot ); if ( watchorg.width != watchnew.width || watchorg.height != watchnew.height ) { $dot.trigger( 'update.dot' ); watchorg = watchnew; } } }, 500 ); } return $dot; }; $dot.unwatch = function() { $(window).unbind( 'resize.dot' + conf.dotid ); if ( watchint ) { clearinterval( watchint ); } return $dot; }; var orgcontent = $dot.contents(), opts = $.extend( true, {}, $.fn.dotdotdot.defaults, o ), conf = {}, watchorg = {}, watchint = null, $inr = null; if ( !( opts.lastcharacter.remove instanceof array ) ) { opts.lastcharacter.remove = $.fn.dotdotdot.defaultarrays.lastcharacter.remove; } if ( !( opts.lastcharacter.noellipsis instanceof array ) ) { opts.lastcharacter.noellipsis = $.fn.dotdotdot.defaultarrays.lastcharacter.noellipsis; } conf.afterelement = getelement( opts.after, $dot ); conf.istruncated = false; conf.dotid = dotid++; $dot.data( 'dotdotdot', true ) .bind_events() .trigger( 'update.dot' ); if ( opts.watch ) { $dot.watch(); } return $dot; }; // public $.fn.dotdotdot.defaults = { 'ellipsis' : '... ', 'wrap' : 'word', 'fallbacktoletter' : true, 'lastcharacter' : {}, 'tolerance' : 0, 'callback' : null, 'after' : null, 'height' : null, 'watch' : false, 'windowresizefix' : true }; $.fn.dotdotdot.defaultarrays = { 'lastcharacter' : { 'remove' : [ ' ', '\u3000', ',', ';', '.', '!', '?' ], 'noellipsis' : [] } }; $.fn.dotdotdot.debug = function( msg ) {}; // private var dotid = 1; function children( $elem, o, after ) { var $elements = $elem.children(), istruncated = false; $elem.empty(); for ( var a = 0, l = $elements.length; a < l; a++ ) { var $e = $elements.eq( a ); $elem.append( $e ); if ( after ) { $elem.append( after ); } if ( test( $elem, o ) ) { $e.remove(); istruncated = true; break; } else { if ( after ) { after.detach(); } } } return istruncated; } function ellipsis( $elem, $d, $i, o, after ) { var istruncated = false; // don't put the ellipsis directly inside these elements var notx = 'a table, thead, tbody, tfoot, tr, col, colgroup, object, embed, param, ol, ul, dl, blockquote, select, optgroup, option, textarea, script, style'; // don't remove these elements even if they are after the ellipsis var noty = 'script, .dotdotdot-keep'; $elem .contents() .detach() .each( function() { var e = this, $e = $(e); if ( typeof e == 'undefined' || ( e.nodetype == 3 && $.trim( e.data ).length == 0 ) ) { return true; } else if ( $e.is( noty ) ) { $elem.append( $e ); } else if ( istruncated ) { return true; } else { $elem.append( $e ); if ( after && !$e.is( o.after ) && !$e.find( o.after ).length ) { $elem[ $elem.is( notx ) ? 'after' : 'append' ]( after ); } if ( test( $i, o ) ) { if ( e.nodetype == 3 ) // node is text { istruncated = ellipsiselement( $e, $d, $i, o, after ); } else { istruncated = ellipsis( $e, $d, $i, o, after ); } if ( !istruncated ) { $e.detach(); istruncated = true; } } if ( !istruncated ) { if ( after ) { after.detach(); } } } } ); return istruncated; } function ellipsiselement( $e, $d, $i, o, after ) { var e = $e[ 0 ]; if ( !e ) { return false; } var txt = gettextcontent( e ), space = ( txt.indexof(' ') !== -1 ) ? ' ' : '\u3000', separator = ( o.wrap == 'letter' ) ? '' : space, textarr = txt.split( separator ), position = -1, midpos = -1, startpos = 0, endpos = textarr.length - 1; // only one word if ( o.fallbacktoletter && startpos == 0 && endpos == 0 ) { separator = ''; textarr = txt.split( separator ); endpos = textarr.length - 1; } while ( startpos <= endpos && !( startpos == 0 && endpos == 0 ) ) { var m = math.floor( ( startpos + endpos ) / 2 ); if ( m == midpos ) { break; } midpos = m; settextcontent( e, textarr.slice( 0, midpos + 1 ).join( separator ) + o.ellipsis ); if ( !test( $i, o ) ) { position = midpos; startpos = midpos; } else { endpos = midpos; // fallback to letter if (o.fallbacktoletter && startpos == 0 && endpos == 0 ) { separator = ''; textarr = textarr[ 0 ].split( separator ); position = -1; midpos = -1; startpos = 0; endpos = textarr.length - 1; } } } if ( position != -1 && !( textarr.length == 1 && textarr[ 0 ].length == 0 ) ) { txt = addellipsis( textarr.slice( 0, position + 1 ).join( separator ), o ); settextcontent( e, txt ); } else { var $w = $e.parent(); $e.detach(); var afterlength = ( after && after.closest($w).length ) ? after.length : 0; if ( $w.contents().length > afterlength ) { e = findlasttextnode( $w.contents().eq( -1 - afterlength ), $d ); } else { e = findlasttextnode( $w, $d, true ); if ( !afterlength ) { $w.detach(); } } if ( e ) { txt = addellipsis( gettextcontent( e ), o ); settextcontent( e, txt ); if ( afterlength && after ) { $(e).parent().append( after ); } } } return true; } function test( $i, o ) { return $i.innerheight() > o.maxheight; } function addellipsis( txt, o ) { while( $.inarray( txt.slice( -1 ), o.lastcharacter.remove ) > -1 ) { txt = txt.slice( 0, -1 ); } if ( $.inarray( txt.slice( -1 ), o.lastcharacter.noellipsis ) < 0 ) { txt += o.ellipsis; } return txt; } function getsizes( $d ) { return { 'width' : $d.innerwidth(), 'height': $d.innerheight() }; } function settextcontent( e, content ) { if ( e.innertext ) { e.innertext = content; } else if ( e.nodevalue ) { e.nodevalue = content; } else if (e.textcontent) { e.textcontent = content; } } function gettextcontent( e ) { if ( e.innertext ) { return e.innertext; } else if ( e.nodevalue ) { return e.nodevalue; } else if ( e.textcontent ) { return e.textcontent; } else { return ""; } } function getprevnode( n ) { do { n = n.previoussibling; } while ( n && n.nodetype !== 1 && n.nodetype !== 3 ); return n; } function findlasttextnode( $el, $top, excludecurrent ) { var e = $el && $el[ 0 ], p; if ( e ) { if ( !excludecurrent ) { if ( e.nodetype === 3 ) { return e; } if ( $.trim( $el.text() ) ) { return findlasttextnode( $el.contents().last(), $top ); } } p = getprevnode( e ); while ( !p ) { $el = $el.parent(); if ( $el.is( $top ) || !$el.length ) { return false; } p = getprevnode( $el[0] ); } if ( p ) { return findlasttextnode( $(p), $top ); } } return false; } function getelement( e, $i ) { if ( !e ) { return false; } if ( typeof e === 'string' ) { e = $(e, $i); return ( e.length ) ? e : false; } return !e.jquery ? false : e; } function gettrueinnerheight( $el ) { var h = $el.innerheight(), a = [ 'paddingtop', 'paddingbottom' ]; for ( var z = 0, l = a.length; z < l; z++ ) { var m = parseint( $el.css( a[ z ] ), 10 ); if ( isnan( m ) ) { m = 0; } h -= m; } return h; } // override jquery.html var _orghtml = $.fn.html; $.fn.html = function( str ) { if ( str != undef && !$.isfunction( str ) && this.data( 'dotdotdot' ) ) { return this.trigger( 'update', [ str ] ); } return _orghtml.apply( this, arguments ); }; // override jquery.text var _orgtext = $.fn.text; $.fn.text = function( str ) { if ( str != undef && !$.isfunction( str ) && this.data( 'dotdotdot' ) ) { str = $( '
' ).text( str ).html(); return this.trigger( 'update', [ str ] ); } return _orgtext.apply( this, arguments ); }; })( jquery );