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 ) |
||
0 ignored issues
–
show
Best Practice
introduced
by
![]() |
|||
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 ) |
||
0 ignored issues
–
show
The variable
HTMLElement seems to be never declared. If this is a global, consider adding a /** global: HTMLElement */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN. ![]() |
|||
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 ) ) |
||
0 ignored issues
–
show
|
|||
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 | { |
||
0 ignored issues
–
show
|
|||
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 ) ) |
||
0 ignored issues
–
show
|
|||
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 ]; |
||
0 ignored issues
–
show
Comprehensibility
Naming
Best Practice
introduced
by
The variable
e already seems to be declared on line 365 . Consider using another variable name or omitting the var keyword.
This check looks for variables that are declared in multiple lines. There may be several reasons for this. In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs. If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared. ![]() |
|||
423 | |||
424 | if ( typeof e != 'undefined' ) |
||
425 | { |
||
426 | var txt = addEllipsis( getTextContent( e ), o ); |
||
0 ignored issues
–
show
Comprehensibility
Naming
Best Practice
introduced
by
The variable
txt already seems to be declared on line 403 . Consider using another variable name or omitting the var keyword.
This check looks for variables that are declared in multiple lines. There may be several reasons for this. In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs. If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared. ![]() |
|||
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 ); |
||
603 |