1212 * *
1313 *********************************************************/
1414
15- export interface IOptions {
15+ export interface IClampOptions {
1616 clamp ?: number | string | 'auto' ;
1717 useNativeClamp ?: boolean ;
1818 splitOnChars ?: Array < string > ;
@@ -21,11 +21,22 @@ export interface IOptions {
2121 truncationHTML ?: string ;
2222}
2323
24- export interface IResponse {
24+ export interface IClampResponse {
2525 original : string ;
2626 clamped : string ;
2727}
2828
29+ /**
30+ * @description Returns the height of an element as an integer (max of scroll/offset/client).
31+ * Note: inline elements return 0 for scrollHeight and clientHeight.
32+ * @param elem
33+ * @returns height in number'
34+ * @author github.com/danmana - copied from https://github.com/josephschmitt/Clamp.js/pull/18
35+ */
36+ const getElemHeight = ( elem : HTMLElement | Element ) : number => {
37+ return Math . max ( elem . scrollHeight , ( < HTMLElement > elem ) . offsetHeight , elem . clientHeight ) ;
38+ }
39+
2940/********************************************************
3041 * *
3142 * UTILITY FUNCTIONS *
@@ -74,7 +85,7 @@ const computeStyle = (elem: HTMLElement | Element, prop: string): string => {
7485 * @returns max lines
7586 */
7687const getMaxLines = ( element : HTMLElement | Element , height ?: number ) : number => {
77- const availHeight = height || element . clientHeight ,
88+ const availHeight = height || getElemHeight ( element ) ,
7889 lineHeight = getLineHeight ( element ) ;
7990 return Math . max ( Math . floor ( availHeight / lineHeight ) , 0 ) ;
8091} ;
@@ -99,12 +110,12 @@ const getMaxHeight = (element: HTMLElement | Element, clmp: number): number => {
99110 */
100111const getLineHeight = ( elem : HTMLElement | Element ) : number => {
101112 const lh = computeStyle ( elem , 'line-height' ) ;
102- if ( lh == 'normal' ) {
113+ if ( lh === 'normal' ) {
103114 // Normal line heights vary from browser to browser. The spec recommends
104115 // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.
105- return parseInt ( computeStyle ( elem , 'font-size' ) ) * 1.2 ;
116+ return parseFloat ( computeStyle ( elem , 'font-size' ) ) * 1.2 ;
106117 }
107- return parseInt ( lh ) ;
118+ return parseFloat ( lh ) ;
108119} ;
109120
110121/**
@@ -113,11 +124,11 @@ const getLineHeight = (elem: HTMLElement | Element): number => {
113124 * @param options config option
114125 * @returns Element's last child.
115126 */
116- const getLastChild = ( elem : HTMLElement | Element , options : IOptions ) : HTMLElement => {
127+ const getLastChild = ( elem : HTMLElement | Element , options : IClampOptions ) : HTMLElement => {
117128 //Current element has children, need to go deeper and get last child as a text node
118129 if (
119- ( elem . lastChild as any ) . children &&
120- ( elem . lastChild as any ) . children . length > 0
130+ ( < HTMLElement > elem . lastChild ) . children &&
131+ ( < HTMLElement > elem . lastChild ) . children . length > 0
121132 ) {
122133 return getLastChild (
123134 Array . prototype . slice . call ( elem . children ) . pop ( ) ,
@@ -129,7 +140,7 @@ const getLastChild = (elem: HTMLElement | Element, options: IOptions): HTMLEleme
129140 ! elem . lastChild ||
130141 ! elem . lastChild . nodeValue ||
131142 elem . lastChild . nodeValue === '' ||
132- elem . lastChild . nodeValue == options . truncationChar
143+ elem . lastChild . nodeValue === options . truncationChar
133144 ) {
134145 elem . lastChild . parentNode . removeChild ( elem . lastChild ) ;
135146 return getLastChild ( elem , options ) ;
@@ -149,7 +160,7 @@ const getLastChild = (elem: HTMLElement | Element, options: IOptions): HTMLEleme
149160const applyEllipsis = (
150161 elem : HTMLElement | Element ,
151162 str : string ,
152- options : IOptions
163+ options : IClampOptions
153164) : void => {
154165 elem . nodeValue = str + options . truncationChar ;
155166} ;
@@ -170,15 +181,15 @@ const truncate = (
170181 element : HTMLElement | Element ,
171182 truncationHTMLContainer : HTMLElement ,
172183 maxHeight : number ,
173- options : IOptions ,
184+ options : IClampOptions ,
174185 config : any = {
175186 splitOnChars : options . splitOnChars . slice ( 0 ) ,
176187 splitChar : options . splitOnChars . slice ( 0 ) [ 0 ] ,
177188 chunks : null ,
178189 lastChunk : null ,
179190 }
180191) : string => {
181- if ( ! maxHeight ) {
192+ if ( ! target || ! maxHeight ) {
182193 return element . innerHTML ;
183194 }
184195
@@ -220,7 +231,7 @@ const truncate = (
220231 // Search produced valid chunks
221232 if ( chunks ) {
222233 // It fits
223- if ( element . clientHeight <= maxHeight ) {
234+ if ( getElemHeight ( element ) <= maxHeight ) {
224235 // There's still more characters to try splitting on, not quite done yet
225236 if ( splitOnChars . length >= 0 && splitChar !== '' ) {
226237 applyEllipsis (
@@ -291,7 +302,7 @@ const truncate = (
291302 * @param element. Element containing the text node to clamp.
292303 * @param options. Options to pass to the clamper.
293304 */
294- export function clamp ( element : Element | HTMLElement , options ?: IOptions ) : IResponse {
305+ export function clamp ( element : Element | HTMLElement , options ?: IClampOptions ) : IClampResponse {
295306 /**
296307 * merge default options with provided options (if any).
297308 */
@@ -307,20 +318,20 @@ export function clamp(element: Element | HTMLElement, options?: IOptions): IResp
307318 const sty = ( < HTMLElement > element ) . style ;
308319 const original = element . innerHTML ;
309320 const supportsNativeClamp =
310- typeof ( < HTMLElement > element ) . style . webkitLineClamp != 'undefined' ;
321+ typeof ( < HTMLElement > element ) . style . webkitLineClamp !== 'undefined' ;
311322 let clampValue = options . clamp ;
312323 const isCSSValue =
313- ( clampValue as string ) . indexOf &&
314- ( ( clampValue as string ) . indexOf ( 'px' ) > - 1 ||
315- ( clampValue as string ) . indexOf ( 'em' ) > - 1 ) ;
324+ ( < string > clampValue ) . indexOf &&
325+ ( ( < string > clampValue ) . indexOf ( 'px' ) > - 1 ||
326+ ( < string > clampValue ) . indexOf ( 'em' ) > - 1 ) ;
316327 let truncationHTMLContainer ;
317328 if ( options . truncationHTML ) {
318329 truncationHTMLContainer = document . createElement ( 'span' ) ;
319330 truncationHTMLContainer . innerHTML = options . truncationHTML ;
320331 }
321332
322333 // CONSTRUCTOR ________________________________________________________________
323- if ( clampValue == 'auto' ) {
334+ if ( clampValue === 'auto' ) {
324335 clampValue = getMaxLines ( element ) ;
325336 } else if ( isCSSValue ) {
326337 clampValue = getMaxLines ( element , parseInt ( clampValue as string ) ) ;
@@ -333,11 +344,11 @@ export function clamp(element: Element | HTMLElement, options?: IOptions): IResp
333344 sty . display = '-webkit-box' ;
334345 sty . webkitLineClamp = clampValue as string ;
335346 if ( isCSSValue ) {
336- sty . height = options . clamp + 'px' ;
347+ sty . height = < string > options . clamp ;
337348 }
338349 } else {
339350 const height = getMaxHeight ( element , clampValue as number ) ;
340- if ( height <= element . clientHeight ) {
351+ if ( height < getElemHeight ( element ) ) {
341352 clamped = truncate (
342353 getLastChild ( element , options ) ,
343354 element ,
0 commit comments