Subversion Repositories Applications.framework

Rev

Blame | Last modification | View Log | RSS feed

/*      
 *      jQuery dotdotdot 1.5.9
 *      
 *      Copyright (c) 2013 Fred Heusschen
 *      www.frebsite.nl
 *
 *      Plugin website:
 *      dotdotdot.frebsite.nl
 *
 *      Dual licensed under the MIT and GPL licenses.
 *      http://en.wikipedia.org/wiki/MIT_License
 *      http://en.wikipedia.org/wiki/GNU_General_Public_License
 */

(function( $ )
{
        if ( $.fn.dotdotdot )
        {
                return;
        }

        $.fn.dotdotdot = function( o )
        {
                if ( this.length == 0 )
                {
                        if ( !o || o.debug !== false )
                        {
                                debug( true, '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' );

                $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' || c instanceof HTMLElement )
                                                {
                                                        c = $('<div />').append( c ).contents();
                                                }
                                                if ( c instanceof $ )
                                                {
                                                        orgContent = c;
                                                }
                                        }

                                        $inr = $dot.wrapInner( '<div class="dotdotdot" />' ).children();
                                        $inr.empty()
                                                .append( orgContent.clone( true ) )
                                                .css({
                                                        'height'        : 'auto',
                                                        'width'         : 'auto',
                                                        'border'        : 'none',
                                                        'padding'       : 0,
                                                        'margin'        : 0
                                                });

                                        var after = false,
                                                trunc = false;

                                        if ( conf.afterElement )
                                        {
                                                after = conf.afterElement.clone( true );
                                                conf.afterElement.remove();
                                        }
                                        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()
                                                .empty()
                                                .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' );
                                                                }, 10
                                                        );
                                                }
                                        }
                                );
                        }
                        else
                        {
                                watchOrg = getSizes( $dot );
                                watchInt = setInterval(
                                        function()
                                        {
                                                var watchNew = getSizes( $dot );
                                                if ( watchOrg.width  != watchNew.width ||
                                                         watchOrg.height != watchNew.height )
                                                {
                                                        $dot.trigger( 'update.dot' );
                                                        watchOrg = getSizes( $dot );
                                                }
                                        }, 100
                                );
                        }
                        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;

                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',
                'lastCharacter': {
                        'remove'                : [ ' ', ',', ';', '.', '!', '?' ],
                        'noEllipsis'    : []
                },
                'tolerance'     : 0,
                'callback'      : null,
                'after'         : null,
                'height'        : null,
                'watch'         : false,
                'windowResizeFix': true,
                'debug'         : false
        };
        

        //      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.remove();
                                }
                        }
                }
                return isTruncated;
        }
        function ellipsis( $elem, $d, $i, o, after )
        {
                var $elements   = $elem.contents(),
                        isTruncated     = false;

                $elem.empty();

                var notx = 'table, thead, tbody, tfoot, tr, col, colgroup, object, embed, param, ol, ul, dl, select, optgroup, option, textarea, script, style';
                for ( var a = 0, l = $elements.length; a < l; a++ )
                {

                        if ( isTruncated )
                        {
                                break;
                        }

                        var e   = $elements[ a ],
                                $e      = $(e);

                        if ( typeof e == 'undefined' )
                        {
                                continue;
                        }

                        $elem.append( $e );
                        if ( after )
                        {
                                $elem[ ( $elem.is( notx ) ) ? 'after' : 'append' ]( after );
                        }
                        if ( e.nodeType == 3 )
                        {
                                if ( test( $i, o ) )
                                {
                                        isTruncated = ellipsisElement( $e, $d, $i, o, after );
                                }
                        }
                        else
                        {
                                isTruncated = ellipsis( $e, $d, $i, o, after );
                        }

                        if ( !isTruncated )
                        {
                                if ( after )
                                {
                                        after.remove();
                                }
                        }
                }
                return isTruncated;
        }
        function ellipsisElement( $e, $d, $i, o, after )
        {
                var isTruncated = false,
                        e = $e[ 0 ];

                if ( typeof e == 'undefined' )
                {
                        return false;
                }

                var seporator   = ( o.wrap == 'letter' ) ? '' : ' ',
                        textArr         = getTextContent( e ).split( seporator ),
                        position        = -1,
                        midPos          = -1,
                        startPos        = 0,
                        endPos          = textArr.length - 1;

                while ( startPos <= endPos )
                {
                        var m = Math.floor( ( startPos + endPos ) / 2 );
                        if ( m == midPos ) 
                        {
                                break;
                        }
                        midPos = m;

                        setTextContent( e, textArr.slice( 0, midPos + 1 ).join( seporator ) + o.ellipsis );

                        if ( !test( $i, o ) )
                        {
                                position = midPos;
                                startPos = midPos; 
                        }
                        else
                        {
                                endPos = midPos;
                        }                               
                }       
        
                if ( position != -1 && !( textArr.length == 1 && textArr[ 0 ].length == 0 ) )
                {
                        var txt = addEllipsis( textArr.slice( 0, position + 1 ).join( seporator ), o );
                        isTruncated = true;
                        setTextContent( e, txt );
                }
                else
                {
                        var $w = $e.parent();
                        $e.remove();

                        var afterLength = ( after ) ? after.length : 0 ;

                        if ( $w.contents().size() > afterLength )
                        {
                                var $n = $w.contents().eq( -1 - afterLength );
                                isTruncated = ellipsisElement( $n, $d, $i, o, after );
                        }
                        else
                        {
                                var $p = $w.prev()
                                var e = $p.contents().eq( -1 )[ 0 ];

                                if ( typeof e != 'undefined' )
                                {
                                        var txt = addEllipsis( getTextContent( e ), o );
                                        setTextContent( e, txt );
                                        if ( after )
                                        {
                                                $p.append( after );
                                        }
                                        $w.remove();
                                        isTruncated = true;
                                }

                        }
                }

                return isTruncated;
        }
        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 getElement( e, $i )
        {
                if ( typeof e == 'undefined' )
                {
                        return false;
                }
                if ( !e )
                {
                        return false;
                }
                if ( typeof e == 'string' )
                {
                        e = $(e, $i);
                        return ( e.length )
                                ? e 
                                : false;
                }
                if ( typeof e == 'object' )
                {
                        return ( typeof e.jquery == 'undefined' )
                                ? false
                                : e;
                }
                return false;
        }
        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;
        }
        function debug( d, m )
        {
                if ( !d )
                {
                        return false;
                }
                if ( typeof m == 'string' )
                {
                        m = 'dotdotdot: ' + m;
                }
                else
                {
                        m = [ 'dotdotdot:', m ];
                }

                if ( typeof window.console != 'undefined' )
                {
                        if ( typeof window.console.log != 'undefined' )
                        {
                                window.console.log( m );
                        }
                }
                return false;
        }
        

        //      override jQuery.html
        var _orgHtml = $.fn.html;
    $.fn.html = function( str ) {
                if ( typeof str != 'undefined' )
                {
                        if ( this.data( 'dotdotdot' ) )
                        {
                                if ( typeof str != 'function' )
                                {
                                        return this.trigger( 'update', [ str ] );
                                }
                        }
                        return _orgHtml.call( this, str );
                }
                return _orgHtml.call( this );
    };


        //      override jQuery.text
        var _orgText = $.fn.text;
    $.fn.text = function( str ) {
                if ( typeof str != 'undefined' )
                {
                        if ( this.data( 'dotdotdot' ) )
                        {
                                var temp = $( '<div />' );
                                temp.text( str );
                                str = temp.html();
                                temp.remove();
                                return this.trigger( 'update', [ str ] );
                        }
                        return _orgText.call( this, str );
                }
        return _orgText.call( this );
    };


})( jQuery );