Skip to content

Commit 0d1206e

Browse files
authored
fix: merged some PRs from the original repo + some other minor fixes. (#3)
* fix": rename interface. * fix: https://github.com/josephschmitt/Clamp.js/pull/18/files * fix: don't append 'px' to opt.clamp. it already has it. copied from josephschmitt/Clamp.js#20 * fix initial height check. copied from: josephschmitt/Clamp.js#44 * fix: minor type * fix: return if `target` is not defined in `truncate` * fix: pass jshint copied from: josephschmitt/Clamp.js#54 * fix: problem with non-integer line height. partially copied from: josephschmitt/Clamp.js#66 * update readme
1 parent 4b62045 commit 0d1206e

File tree

3 files changed

+40
-24
lines changed

3 files changed

+40
-24
lines changed

readme.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,16 @@
55
![license](https://img.shields.io/github/license/aamir1995/clamp.ts)
66

77
# clamp.ts
8-
TypeScript fork of [clamp.js](https://github.com/josephschmitt/Clamp.js)
8+
TypeScript fork of [clamp.js](https://github.com/josephschmitt/Clamp.js) - all of the relevant unmerged PRs from the original repo are merged.
99

1010
Clamps (ie. cuts off) an HTML element's content by adding ellipsis to it if the
1111
content inside is too long.
1212

13+
Install by running:
14+
```
15+
npm install clamp.ts
16+
```
17+
1318
Demo: https://stackblitz.com/edit/typescript-zi38tc?file=index.ts
1419

1520
## Sample Usage

src/clamp.ts

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
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
*/
7687
const 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
*/
100111
const 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
149160
const 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,

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { clamp, IOptions, IResponse } from './clamp';
1+
export { clamp, IClampOptions, IClampResponse } from './clamp';

0 commit comments

Comments
 (0)