Subversion Repositories Applications.framework

Rev

Details | Last modification | View Log | RSS feed

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