vendor: 10,375 bytes, lines 1-282
1 2/*! 3* Clamp.js 0.5.1 4* 5* Copyright 2011-2013, Joseph Schmitt http://joe.sh 6* Released under the WTFPL license 7* http://sam.zoy.org/wtfpl/ 8*/ 9 10(function(){ 11 /** 12 * Clamps a text node. 13 * @param {HTMLElement} element. Element containing the text node to clamp. 14 * @param {Object} options. Options to pass to the clamper. 15 */ 16 function clamp(element, options) { 17 options = options || {}; 18 19 var self = this, 20 win = window, 21 opt = { 22 clamp: options.clamp || 2, 23 useNativeClamp: typeof(options.useNativeClamp) != 'undefined' ? options.useNativeClamp : true, 24 splitOnChars: options.splitOnChars || ['.', '-', 'â', 'â', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces). 25 animate: options.animate || false, 26 truncationChar: options.truncationChar || 'â¦', 27 truncationHTML: options.truncationHTML 28 }, 29 30 sty = element.style, 31 originalText = element.innerHTML, 32 33 supportsNativeClamp = typeof(element.style.webkitLineClamp) != 'undefined', 34 clampValue = opt.clamp, 35 isCSSValue = clampValue.indexOf && (clampValue.indexOf('px') > -1 || clampValue.indexOf('em') > -1), 36 truncationHTMLContainer; 37 38 if (opt.truncationHTML) { 39 truncationHTMLContainer = document.createElement('span'); 40 truncationHTMLContainer.innerHTML = opt.truncationHTML; 41 } 42 43 44// UTILITY FUNCTIONS __________________________________________________________ 45 46 /** 47 * Return the current style for an element. 48 * @param {HTMLElement} elem The element to compute. 49 * @param {string} prop The style property. 50 * @returns {number} 51 */ 52 function computeStyle(elem, prop) { 53 if (!win.getComputedStyle) { 54 win.getComputedStyle = function(el, pseudo) { 55 this.el = el; 56 this.getPropertyValue = function(prop) { 57 var re = /(\-([a-z]){1})/g; 58 if (prop == 'float') prop = 'styleFloat'; 59 if (re.test(prop)) { 60 prop = prop.replace(re, function () { 61 return arguments[2].toUpperCase(); 62 }); 63 } 64 return el.currentStyle && el.currentStyle[prop] ? el.currentStyle[prop] : null; 65 } 66 return this; 67 } 68 } 69 70 return win.getComputedStyle(elem, null).getPropertyValue(prop); 71 } 72 73 /** 74 * Returns the maximum number of lines of text that should be rendered based 75 * on the current height of the element and the line-height of the text. 76 */ 77 function getMaxLines(height) { 78 var availHeight = height || element.clientHeight, 79 lineHeight = getLineHeight(element); 80 81 return Math.max(Math.floor(availHeight/lineHeight), 0); 82 } 83 84 /** 85 * Returns the maximum height a given element should have based on the line- 86 * height of the text and the given clamp value. 87 */ 88 function getMaxHeight(clmp) { 89 var lineHeight = getLineHeight(element); 90 return lineHeight * clmp; 91 } 92 93 /** 94 * Returns the line-height of an element as an integer. 95 */ 96 function getLineHeight(elem) { 97 var lh = computeStyle(elem, 'line-height'); 98 if (lh == 'normal') { 99 // Normal line heights vary from browser to browser. The spec recommends 100 // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff. 101 lh = parseInt(computeStyle(elem, 'font-size')) * 1.2; 102 } 103 return parseInt(lh); 104 } 105 106 107// MEAT AND POTATOES (MMMM, POTATOES...) ______________________________________ 108 var splitOnChars = opt.splitOnChars.slice(0), 109 splitChar = splitOnChars[0], 110 chunks, 111 lastChunk; 112 113 /** 114 * Gets an element's last child. That may be another node or a node's contents. 115 */ 116 function getLastChild(elem) { 117 //Current element has children, need to go deeper and get last child as a text node 118 if (elem.lastChild.children && elem.lastChild.children.length > 0) { 119 return getLastChild(Array.prototype.slice.call(elem.children).pop()); 120 } 121 //This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying 122 else if (!elem.lastChild || !elem.lastChild.nodeValue || elem.lastChild.nodeValue == '' || elem.lastChild.nodeValue == opt.truncationChar) { 123 elem.lastChild.parentNode.removeChild(elem.lastChild); 124 return getLastChild(element); 125 } 126 //This is the last child we want, return it 127 else { 128 return elem.lastChild; 129 } 130 } 131 132 /** 133 * Removes one character at a time from the text until its width or 134 * height is beneath the passed-in max param. 135 */ 136 function truncate(target, maxHeight) { 137 if (!maxHeight) {return;} 138 139 /** 140 * Resets global variables. 141 */ 142 function reset() { 143 splitOnChars = opt.splitOnChars.slice(0); 144 splitChar = splitOnChars[0]; 145 chunks = null; 146 lastChunk = null; 147 } 148 149 var nodeValue = target.nodeValue.replace(opt.truncationChar, ''); 150 151 //Grab the next chunks 152 if (!chunks) { 153 //If there are more characters to try, grab the next one 154 if (splitOnChars.length > 0) { 155 splitChar = splitOnChars.shift(); 156 } 157 //No characters to chunk by. Go character-by-character 158 else { 159 splitChar = ''; 160 } 161 162 chunks = nodeValue.split(splitChar); 163 } 164 165 //If there are chunks left to remove, remove the last one and see if 166 // the nodeValue fits. 167 if (chunks.length > 1) { 168 // console.log('chunks', chunks); 169 lastChunk = chunks.pop(); 170 // console.log('lastChunk', lastChunk); 171 applyEllipsis(target, chunks.join(splitChar)); 172 } 173 //No more chunks can be removed using this character 174 else { 175 chunks = null; 176 } 177 178 //Insert the custom HTML before the truncation character 179 if (truncationHTMLContainer) { 180 target.nodeValue = target.nodeValue.replace(opt.truncationChar, ''); 181 element.innerHTML = target.nodeValue + ' ' + truncationHTMLContainer.innerHTML + opt.truncationChar; 182 } 183 184 //Search produced valid chunks 185 if (chunks) { 186 //It fits 187 if (element.clientHeight <= maxHeight) { 188 //There's still more characters to try splitting on, not quite done yet 189 if (splitOnChars.length >= 0 && splitChar != '') { 190 applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk); 191 chunks = null; 192 } 193 //Finished! 194 else { 195 return element.innerHTML; 196 } 197 } 198 } 199 //No valid chunks produced 200 else { 201 //No valid chunks even when splitting by letter, time to move 202 //on to the next node 203 if (splitChar == '') { 204 applyEllipsis(target, ''); 205 target = getLastChild(element); 206 207 reset(); 208 } 209 } 210 211 //If you get here it means still too big, let's keep truncating 212 if (opt.animate) { 213 setTimeout(function() { 214 truncate(target, maxHeight); 215 }, opt.animate === true ? 10 : opt.animate); 216 } 217 else { 218 return truncate(target, maxHeight); 219 } 220 } 221 222 function applyEllipsis(elem, str) { 223 elem.nodeValue = str + opt.truncationChar; 224 } 225 226 227// CONSTRUCTOR ________________________________________________________________ 228 229 if (clampValue == 'auto') { 230 clampValue = getMaxLines(); 231 } 232 else if (isCSSValue) { 233 clampValue = getMaxLines(parseInt(clampValue)); 234 } 235 236 var clampedText; 237 if (supportsNativeClamp && opt.useNativeClamp) { 238 sty.overflow = 'hidden'; 239 sty.textOverflow = 'ellipsis'; 240 sty.webkitBoxOrient = 'vertical'; 241 sty.display = 'inline-block'; 242 sty.width = '110px'; 243 sty.whiteSpace ='pre-line'; 244 sty.webkitLineClamp = clampValue; 245 246 if (isCSSValue) { 247 sty.height = opt.clamp + 'px'; 248 } 249 } 250 else { 251 var height = getMaxHeight(clampValue); 252 253 /* if((navigator.userAgent.indexOf('Trident') != -1 && navigator.userAgent.indexOf('MSIE') == -1) || /Edge\/\d./i.test(navigator.userAgent)) { 254 255 if(element.offsetWidth+2 > element.scrollWidth){ 256 sty.whiteSpace = 'pre-line'; 257 sty.width = '110px'; 258 }else{ 259 260 sty.whiteSpace = 'nowrap'; 261 sty.width = '120px'; 262 sty.overflow = 'hidden'; 263 sty.textOverflow = 'ellipsis'; 264// sty.fontSize = '13px'; 265 266 }}*/ 267 268 if (height <= element.clientHeight) { 269 clampedText = truncate(getLastChild(element), height); 270 } 271 272 } 273 274 return { 275 'original': originalText, 276 'clamped': clampedText 277 } 278 } 279 280 window.$clamp = clamp; 281})(); 282
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.