New file |
0,0 → 1,602 |
/* |
* 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 ); |