-
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.js
109 lines (100 loc) · 2.56 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const ELLIPSIS_CHARACTER = '\u2026'
function lineClamp (rootElement, lineCount, options) {
rootElement.style.cssText +=
'overflow:hidden;overflow-wrap:break-word;word-wrap:break-word'
const maximumHeight =
(lineCount || 1) *
parseInt(window.getComputedStyle(rootElement).lineHeight, 10)
// Exit if text does not overflow `rootElement`.
if (rootElement.scrollHeight <= maximumHeight) {
return false
}
return truncateElementNode(
rootElement,
rootElement,
maximumHeight,
(options && options.ellipsis) || ELLIPSIS_CHARACTER
)
}
function truncateElementNode (
element,
rootElement,
maximumHeight,
ellipsisCharacter
) {
const childNodes = element.childNodes
let i = childNodes.length - 1
while (i > -1) {
const childNode = childNodes[i--]
if (
(childNode.nodeType === 1 &&
truncateElementNode(
childNode,
rootElement,
maximumHeight,
ellipsisCharacter
)) ||
(childNode.nodeType === 3 &&
truncateTextNode(
childNode,
rootElement,
maximumHeight,
ellipsisCharacter
))
) {
return true
}
element.removeChild(childNode)
}
return false
}
function truncateTextNode (
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
) {
let lastIndexOfWhitespace
let textContent = textNode.textContent
while (textContent.length > 1) {
lastIndexOfWhitespace = textContent.lastIndexOf(' ')
if (lastIndexOfWhitespace === -1) {
break
}
textNode.textContent = textContent.substring(0, lastIndexOfWhitespace)
if (rootElement.scrollHeight <= maximumHeight) {
textNode.textContent = textContent
break
}
textContent = textNode.textContent
}
return truncateTextNodeByCharacter(
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
)
}
const TRAILING_WHITESPACE_AND_PUNCTUATION_REGEX = /[ .,;!?'‘’“”\-–—]+$/
function truncateTextNodeByCharacter (
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
) {
let textContent = textNode.textContent
let length = textContent.length
while (length > 1) {
// Trim off one trailing character and any trailing punctuation and whitespace.
textContent = textContent
.substring(0, length - 1)
.replace(TRAILING_WHITESPACE_AND_PUNCTUATION_REGEX, '')
length = textContent.length
textNode.textContent = textContent + ellipsisCharacter
if (rootElement.scrollHeight <= maximumHeight) {
return true
}
}
return false
}
module.exports = lineClamp