1/* 2 * jQuery dotdotdot 1.5.6 3 * 4 * Copyright (c) 2013 Fred Heusschen 5 * www.frebsite.nl 6 * 7 * Plugin website: 8 * dotdotdot.frebsite.nl 9 * 10 * Dual licensed under the MIT and GPL licenses. 11 * http://en.wikipedia.org/wiki/MIT_License 12 * http://en.wikipedia.org/wiki/GNU_General_Public_License 13 */ 14 15 16(function( $ ) 17{ 18 if ( $.fn.dotdotdot ) 19 { 20 return; 21 } 22 23 $.fn.dotdotdot = function( o ) 24 { 25 if ( this.length == 0 ) 26 { 27 debug( true, 'No element found for "' + this.selector + '".' ); 28 return this; 29 } 30 if ( this.length > 1 ) 31 { 32 return this.each( 33 function() 34 { 35 $(this).dotdotdot( o ); 36 } 37 ); 38 } 39 40 41 var $dot = this; 42 43 if ( $dot.data( 'dotdotdot' ) ) 44 { 45 $dot.trigger( 'destroy.dot' ); 46 } 47 48 $dot.bind_events = function() 49 { 50 $dot.bind( 51 'update.dot', 52 function( e, c ) 53 { 54 e.preventDefault(); 55 e.stopPropagation(); 56 57 opts.maxHeight = ( typeof opts.height == 'number' ) 58 ? opts.height 59 : getTrueInnerHeight( $dot ); 60 61 opts.maxHeight += opts.tolerance; 62 63 if ( typeof c != 'undefined' ) 64 { 65 if ( typeof c == 'string' || c instanceof HTMLElement ) 66 { 67 c = $('<div />').append( c ).contents(); 68 } 69 if ( c instanceof $ ) 70 { 71 orgContent = c; 72 } 73 } 74 75 $inr = $dot.wrapInner( '<div class="dotdotdot" />' ).children(); 76 $inr.empty() 77 .append( orgContent.clone( true ) ) 78 .css({ 79 'height' : 'auto', 80 'width' : 'auto', 81 'border' : 'none', 82 'padding' : 0, 83 'margin' : 0 84 }); 85 86 var after = false, 87 trunc = false; 88 89 if ( conf.afterElement ) 90 { 91 after = conf.afterElement.clone( true ); 92 conf.afterElement.remove(); 93 } 94 if ( test( $inr, opts ) ) 95 { 96 if ( opts.wrap == 'children' ) 97 { 98 trunc = children( $inr, opts, after ); 99 } 100 else 101 { 102 trunc = ellipsis( $inr, $dot, $inr, opts, after ); 103 } 104 } 105 $inr.replaceWith( $inr.contents() ); 106 $inr = null; 107 108 if ( $.isFunction( opts.callback ) ) 109 { 110 opts.callback.call( $dot[ 0 ], trunc, orgContent ); 111 } 112 113 conf.isTruncated = trunc; 114 return trunc; 115 } 116 117 ).bind( 118 'isTruncated.dot', 119 function( e, fn ) 120 { 121 e.preventDefault(); 122 e.stopPropagation(); 123 124 if ( typeof fn == 'function' ) 125 { 126 fn.call( $dot[ 0 ], conf.isTruncated ); 127 } 128 return conf.isTruncated; 129 } 130 131 ).bind( 132 'originalContent.dot', 133 function( e, fn ) 134 { 135 e.preventDefault(); 136 e.stopPropagation(); 137 138 if ( typeof fn == 'function' ) 139 { 140 fn.call( $dot[ 0 ], orgContent ); 141 } 142 return orgContent; 143 } 144 145 ).bind( 146 'destroy.dot', 147 function( e ) 148 { 149 e.preventDefault(); 150 e.stopPropagation(); 151 152 $dot.unwatch() 153 .unbind_events() 154 .empty() 155 .append( orgContent ) 156 .data( 'dotdotdot', false ); 157 } 158 ); 159 return $dot; 160 }; // /bind_events 161 162 $dot.unbind_events = function() 163 { 164 $dot.unbind('.dot'); 165 return $dot; 166 }; // /unbind_events 167 168 $dot.watch = function() 169 { 170 $dot.unwatch(); 171 if ( opts.watch == 'window' ) 172 { 173 var $window = $(window), 174 _wWidth = $window.width(), 175 _wHeight = $window.height(); 176 177 $window.bind( 178 'resize.dot' + conf.dotId, 179 function() 180 { 181 if ( _wWidth != $window.width() || _wHeight != $window.height() || !opts.windowResizeFix ) 182 { 183 _wWidth = $window.width(); 184 _wHeight = $window.height(); 185 186 if ( watchInt ) 187 { 188 clearInterval( watchInt ); 189 } 190 watchInt = setTimeout( 191 function() 192 { 193 $dot.trigger( 'update.dot' ); 194 }, 10 195 ); 196 } 197 } 198 ); 199 } 200 else 201 { 202 watchOrg = getSizes( $dot ); 203 watchInt = setInterval( 204 function() 205 { 206 var watchNew = getSizes( $dot ); 207 if ( watchOrg.width != watchNew.width || 208 watchOrg.height != watchNew.height ) 209 { 210 $dot.trigger( 'update.dot' ); 211 watchOrg = getSizes( $dot ); 212 } 213 }, 100 214 ); 215 } 216 return $dot; 217 }; 218 $dot.unwatch = function() 219 { 220 $(window).unbind( 'resize.dot' + conf.dotId ); 221 if ( watchInt ) 222 { 223 clearInterval( watchInt ); 224 } 225 return $dot; 226 }; 227 228 var orgContent = $dot.contents(), 229 opts = $.extend( true, {}, $.fn.dotdotdot.defaults, o ),
230 conf = {}, 231 watchOrg = {}, 232 watchInt = null, 233 $inr = null; 234 235 conf.afterElement = getElement( opts.after, $dot ); 236 conf.isTruncated = false; 237 conf.dotId = dotId++; 238 239 240 $dot.data( 'dotdotdot', true ) 241 .bind_events() 242 .trigger( 'update.dot' ); 243 244 if ( opts.watch ) 245 { 246 $dot.watch(); 247 } 248 249 return $dot; 250 }; 251 252 253 // public 254 $.fn.dotdotdot.defaults = { 255 'ellipsis' : '... ', 256 'wrap' : 'word', 257 'lastCharacter': { 258 'remove' : [ ' ', ',', ';', '.', '!', '?' ], 259 'noEllipsis' : [] 260 }, 261 'tolerance' : 0, 262 'callback' : null, 263 'after' : null, 264 'height' : null, 265 'watch' : false, 266 'windowResizeFix': true, 267 'debug' : false 268 }; 269 270 271 // private 272 var dotId = 1; 273 274 function children( $elem, o, after ) 275 { 276 var $elements = $elem.children(), 277 isTruncated = false; 278 279 $elem.empty(); 280 281 for ( var a = 0, l = $elements.length; a < l; a++ ) 282 { 283 var $e = $elements.eq( a ); 284 $elem.append( $e ); 285 if ( after ) 286 { 287 $elem.append( after ); 288 } 289 if ( test( $elem, o ) ) 290 { 291 $e.remove(); 292 isTruncated = true; 293 break; 294 } 295 else 296 { 297 if ( after ) 298 { 299 after.remove(); 300 } 301 } 302 } 303 return isTruncated; 304 } 305 function ellipsis( $elem, $d, $i, o, after ) 306 { 307 var $elements = $elem.contents(), 308 isTruncated = false; 309 310 $elem.empty(); 311 312 var notx = 'table, thead, tbody, tfoot, tr, col, colgroup, object, embed, param, ol, ul, dl, select, optgroup, option, textarea, script, style'; 313 for ( var a = 0, l = $elements.length; a < l; a++ ) 314 { 315 316 if ( isTruncated ) 317 { 318 break; 319 } 320 321 var e = $elements[ a ], 322 $e = $(e); 323 324 if ( typeof e == 'undefined' ) 325 { 326 continue; 327 } 328 329 $elem.append( $e ); 330 if ( after ) 331 { 332 $elem[ ( $elem.is( notx ) ) ? 'after' : 'append' ]( after ); 333 } 334 if ( e.nodeType == 3 ) 335 { 336 if ( test( $i, o ) ) 337 { 338 isTruncated = ellipsisElement( $e, $d, $i, o, after ); 339 } 340 } 341 else 342 { 343 isTruncated = ellipsis( $e, $d, $i, o, after ); 344 } 345 346 if ( !isTruncated ) 347 { 348 if ( after ) 349 { 350 after.remove(); 351 } 352 } 353 } 354 return isTruncated; 355 } 356 function ellipsisElement( $e, $d, $i, o, after ) 357 { 358 var isTruncated = false, 359 e = $e[ 0 ]; 360 361 if ( typeof e == 'undefined' ) 362 { 363 return false; 364 } 365 366 var seporator = ( o.wrap == 'letter' ) ? '' : ' ', 367 textArr = getTextContent( e ).split( seporator ), 368 position = -1, 369 midPos = -1, 370 startPos = 0, 371 endPos = textArr.length - 1; 372 373 while ( startPos <= endPos ) 374 { 375 var m = Math.floor( ( startPos + endPos ) / 2 ); 376 if ( m == midPos ) 377 { 378 break; 379 } 380 midPos = m; 381 382 setTextContent( e, textArr.slice( 0, midPos + 1 ).join( seporator ) + o.ellipsis ); 383 384 if ( !test( $i, o ) ) 385 { 386 position = midPos; 387 startPos = midPos; 388 } 389 else 390 { 391 endPos = midPos; 392 } 393 } 394 395 if ( position != -1 && !( textArr.length == 1 && textArr[ 0 ].length == 0 ) ) 396 { 397 var txt = addEllipsis( textArr.slice( 0, position + 1 ).join( seporator ), o ); 398 isTruncated = true; 399 setTextContent( e, txt ); 400 } 401 else 402 { 403 var $w = $e.parent(); 404 $e.remove(); 405 406 var afterLength = ( after ) ? after.length : 0 ; 407 408 if ( $w.contents().size() > afterLength ) 409 { 410 var $n = $w.contents().eq( -1 - afterLength ); 411 isTruncated = ellipsisElement( $n, $d, $i, o, after ); 412 } 413 else 414 { 415 var e = $w.prev().contents().eq( -1 )[ 0 ]; 416 417 if ( typeof e != 'undefined' ) 418 { 419 var txt = addEllipsis( getTextContent( e ), o ); 420 setTextContent( e, txt ); 421 $w.remove(); 422 isTruncated = true; 423 } 424 425 } 426 } 427 428 return isTruncated; 429 } 430 function test( $i, o ) 431 { 432 return $i.innerHeight() > o.maxHeight; 433 } 434 function addEllipsis( txt, o ) 435 { 436 while( $.inArray( txt.slice( -1 ), o.lastCharacter.remove ) > -1 ) 437 { 438 txt = txt.slice( 0, -1 ); 439 } 440 if ( $.inArray( txt.slice( -1 ), o.lastCharacter.noEllipsis ) < 0 ) 441 { 442 txt += o.ellipsis; 443 } 444 return txt; 445 } 446 function getSizes( $d ) 447 { 448 return { 449 'width' : $d.innerWidth(), 450 'height': $d.innerHeight() 451 }; 452 } 453 function setTextContent( e, content ) 454 { 455 if ( e.innerText ) 456 { 457 e.innerText = content; 458 } 459 else if ( e.nodeValue ) 460 { 461 e.nodeValue = content; 462 } 463 else if (e.textContent) 464 { 465 e.textContent = content; 466 } 467 468 } 469 function getTextContent( e ) 470 { 471 if ( e.innerText ) 472 { 473 return e.innerText; 474 } 475 else if ( e.nodeValue ) 476 {
477 return e.nodeValue; 478 } 479 else if ( e.textContent ) 480 { 481 return e.textContent; 482 } 483 else 484 { 485 return ""; 486 } 487 } 488 function getElement( e, $i ) 489 { 490 if ( typeof e == 'undefined' ) 491 { 492 return false; 493 } 494 if ( !e ) 495 { 496 return false; 497 } 498 if ( typeof e == 'string' ) 499 { 500 e = $(e, $i); 501 return ( e.length ) 502 ? e 503 : false; 504 } 505 if ( typeof e == 'object' ) 506 { 507 return ( typeof e.jquery == 'undefined' ) 508 ? false 509 : e; 510 } 511 return false; 512 } 513 function getTrueInnerHeight( $el ) 514 { 515 var h = $el.innerHeight(), 516 a = [ 'paddingTop', 'paddingBottom' ]; 517 518 for ( var z = 0, l = a.length; z < l; z++ ) { 519 var m = parseInt( $el.css( a[ z ] ), 10 ); 520 if ( isNaN( m ) ) 521 { 522 m = 0; 523 } 524 h -= m; 525 } 526 return h; 527 } 528 function debug( d, m ) 529 { 530 if ( !d ) 531 { 532 return false; 533 } 534 if ( typeof m == 'string' ) 535 { 536 m = 'dotdotdot: ' + m; 537 } 538 else 539 { 540 m = [ 'dotdotdot:', m ]; 541 } 542 543 if ( typeof window.console != 'undefined' ) 544 { 545 if ( typeof window.console.log != 'undefined' ) 546 { 547 window.console.log( m ); 548 } 549 } 550 return false; 551 } 552 553 554 // override jQuery.html 555 var _orgHtml = $.fn.html; 556 $.fn.html = function( str ) { 557 if ( typeof str != 'undefined' ) 558 { 559 if ( this.data( 'dotdotdot' ) ) 560 { 561 if ( typeof str != 'function' ) 562 { 563 return this.trigger( 'update', [ str ] ); 564 } 565 } 566 return _orgHtml.call( this, str ); 567 } 568 return _orgHtml.call( this ); 569 }; 570 571 572 // override jQuery.text 573 var _orgText = $.fn.text; 574 $.fn.text = function( str ) { 575 if ( typeof str != 'undefined' ) 576 { 577 if ( this.data( 'dotdotdot' ) ) 578 { 579 var temp = $( '<div />' ); 580 temp.text( str ); 581 str = temp.html(); 582 temp.remove(); 583 return this.trigger( 'update', [ str ] ); 584 } 585 return _orgText.call( this, str ); 586 } 587 return _orgText.call( this ); 588 }; 589 590 591})( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.