PageRenderTime 48ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/files/jquery.dotdotdot/1.5.10/jquery.dotdotdot.js

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