forked from dollarshaveclub/shave
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshave.es.js
75 lines (63 loc) · 2.94 KB
/
shave.es.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
/**
shave - Shave is a javascript plugin that truncates multi-line text within a html element based on set max height
@version v2.5.7
@link https://github.com/dollarshaveclub/shave#readme
@author Jeff Wainwright <[email protected]> (jeffry.in)
@license MIT
**/
function shave(target, maxHeight) {
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
if (typeof maxHeight === 'undefined' || isNaN(maxHeight)) throw Error('maxHeight is required');
var els = typeof target === 'string' ? document.querySelectorAll(target) : target;
if (!els) return;
var character = opts.character || '…';
var classname = opts.classname || 'js-shave';
var spaces = typeof opts.spaces === 'boolean' ? opts.spaces : true;
var charHtml = "<span class=\"js-shave-char\">".concat(character, "</span>");
if (!('length' in els)) els = [els];
for (var i = 0; i < els.length; i += 1) {
var el = els[i];
var styles = el.style;
var span = el.querySelector(".".concat(classname));
var textProp = el.textContent === undefined ? 'innerText' : 'textContent'; // If element text has already been shaved
if (span) {
// Remove the ellipsis to recapture the original text
el.removeChild(el.querySelector('.js-shave-char'));
el[textProp] = el[textProp]; // eslint-disable-line
// nuke span, recombine text
}
var fullText = el[textProp];
var words = spaces ? fullText.split(' ') : fullText; // If 0 or 1 words, we're done
if (words.length < 2) continue; // Temporarily remove any CSS height for text height calculation
var heightStyle = styles.height;
styles.height = 'auto';
var maxHeightStyle = styles.maxHeight;
styles.maxHeight = 'none'; // If already short enough, we're done
if (el.offsetHeight <= maxHeight) {
styles.height = heightStyle;
styles.maxHeight = maxHeightStyle;
continue;
} // Binary search for number of words which can fit in allotted height
var max = words.length - 1;
var min = 0;
var pivot = void 0;
while (min < max) {
pivot = min + max + 1 >> 1; // eslint-disable-line no-bitwise
el[textProp] = spaces ? words.slice(0, pivot).join(' ') : words.slice(0, pivot);
el.insertAdjacentHTML('beforeend', charHtml);
if (el.offsetHeight > maxHeight) max = pivot - 1;else min = pivot;
}
el[textProp] = spaces ? words.slice(0, max).join(' ') : words.slice(0, max);
el.insertAdjacentHTML('beforeend', charHtml);
var diff = spaces ? " ".concat(words.slice(max).join(' ')) : words.slice(max);
var shavedText = document.createTextNode(diff);
var elWithShavedText = document.createElement('span');
elWithShavedText.classList.add(classname);
elWithShavedText.style.display = 'none';
elWithShavedText.appendChild(shavedText);
el.insertAdjacentElement('beforeend', elWithShavedText);
styles.height = heightStyle;
styles.maxHeight = maxHeightStyle;
}
}
export default shave;