Launch Week Day 2: Introducing Reports: An Extensible Reporting Framework for Socket Data.Learn More
Socket
Book a DemoSign in
Socket

line-clamp

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

line-clamp - npm Package Compare versions

Comparing version
0.0.4
to
0.0.5
+1
.gitattributes
example/* linguist-documentation
notifications:
email: false
language: node_js
node_js:
- 'node'
script:
- yarn lint
<!DOCTYPE html>
<html>
<head>
<title>line-clamp</title>
<meta charset="utf-8">
<style>
.line-clamp {
width: 100px;
line-height: 20px;
}
</style>
</head>
<body>
<div class="line-clamp">
Lorem ipsum dolor sit amet, <strong>consectetur adipiscing</strong> elit.
</div>
<script src="/bundle.js"></script>
<script>
const element = document.querySelector('.line-clamp')
lineClamp(element, 3)
</script>
</body>
</html>
function truncateTextNode (
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
) {
truncateTextNodeByWord(
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
)
return truncateTextNodeByCharacter(
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
)
}
function truncateTextNodeByWord (textNode, rootElement, maximumHeight) {
var lastIndexOfWhitespace
var textContent = textNode.textContent
while (textContent.length > 1) {
lastIndexOfWhitespace = textContent.lastIndexOf(' ')
if (lastIndexOfWhitespace == -1) {
return
}
textNode.textContent = textContent.substring(0, lastIndexOfWhitespace)
if (rootElement.scrollHeight <= maximumHeight) {
textNode.textContent = textContent
return
}
textContent = textNode.textContent
}
}
var TRAILING_WHITESPACE_AND_PUNCTUATION_REGEX = /[ .,;!?'‘’“”\-–—]+$/
function truncateTextNodeByCharacter (
textNode,
rootElement,
maximumHeight,
ellipsisCharacter
) {
var textContent = textNode.textContent
var 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
}
function truncateElementNode (
element,
rootElement,
maximumHeight,
ellipsisCharacter
) {
var childNodes = element.childNodes
var i = childNodes.length - 1
while (i > -1) {
var childNode = childNodes[i--]
var nodeType = childNode.nodeType
if (
(nodeType == 1 &&
truncateElementNode(
childNode,
rootElement,
maximumHeight,
ellipsisCharacter
)) ||
(nodeType == 3 &&
truncateTextNode(
childNode,
rootElement,
maximumHeight,
ellipsisCharacter
))
) {
return true
}
element.removeChild(childNode)
}
return false
}
var ELLIPSIS_CHARACTER = '\u2026'
module.exports = function (rootElement, lineCount, options) {
rootElement.style.cssText +=
'overflow:hidden;overflow-wrap:break-word;word-wrap:break-word'
var maximumHeight =
(lineCount || 1) *
parseInt(window.getComputedStyle(rootElement).lineHeight, 10)
// Exit if text does not overflow `rootElement`.
if (rootElement.scrollHeight <= maximumHeight) {
return
}
truncateElementNode(
rootElement,
rootElement,
maximumHeight,
(options && options.ellipsis) || ELLIPSIS_CHARACTER
)
}

Sorry, the diff of this file is too big to display

+1
-1
The MIT License (MIT)
Copyright (c) 2016 Lim Yuan Qing
Copyright (c) 2018 Lim Yuan Qing

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"name": "line-clamp",
"version": "0.0.4",
"description": "Truncate multi-line text in a DOM element.",
"version": "0.0.5",
"description": "Line clamp a DOM element in vanilla JavaScript.",
"author": "Lim Yuan Qing",
"license": "MIT",
"main": "lib/index.js",
"repository": {

@@ -12,32 +11,15 @@ "type": "git",

},
"files": [
"lib",
"src"
],
"devDependencies": {
"babel-core": "6.7.2",
"babel-eslint": "5.0.0",
"babel-preset-es2015": "6.6.0",
"babelify": "7.2.0",
"browserify": "13.0.0",
"del": "2.2.0",
"ecstatic": "1.4.0",
"gulp": "3.9.1",
"gulp-babel": "6.1.2",
"gulp-eslint": "1.1.1",
"gulp-util": "3.0.7",
"nopt": "3.0.6",
"opn": "4.0.1",
"require-dir": "0.3.0",
"run-sequence": "1.1.5",
"tape": "4.5.1",
"vinyl-buffer": "1.0.0",
"vinyl-source-stream": "1.1.0",
"watchify": "3.7.0"
"concurrently": "^3.5.1",
"ecstatic": "^3.2.0",
"gzip-size-cli": "^2.1.0",
"opn-cli": "^3.1.0",
"prettier-standard": "^8.0.0",
"uglify-js": "^3.3.11",
"watchify": "^3.10.0"
},
"scripts": {
"example": "gulp example",
"lint": "gulp lint",
"prepublish": "gulp build",
"test": "echo \"Error: no test specified\" && exit 1"
"start": "concurrently \"watchify index.js --standalone lineClamp --outfile example/bundle.js\" \"ecstatic example --port 8080\" \"opn 'http://0.0.0.0:8080/'\"",
"lint": "prettier-standard index.js test/index.js --no-semi --single-quote --write",
"weight": "uglifyjs index.js --compress --mangle --toplevel | gzip-size"
},

@@ -44,0 +26,0 @@ "keywords": [

+36
-45
# line-clamp [![npm Version](http://img.shields.io/npm/v/line-clamp.svg?style=flat)](https://www.npmjs.com/package/line-clamp) [![Build Status](https://img.shields.io/travis/yuanqing/line-clamp.svg?branch=master&style=flat)](https://travis-ci.org/yuanqing/line-clamp)
> Truncate multi-line text in a DOM element.
> Line clamp a DOM element in vanilla JavaScript.
## Features
- Pure JavaScript; does *not* use [`-webkit-line-clamp`](https://css-tricks.com/line-clampin/)
- Works even if the given element contains nested DOM nodes
- Supports appending a custom string instead of an ellipsis
- Exit if we detect that no truncation is necessary (ie. content does not overflow the element)
- Exit if we detect that no truncation is necessary (ie. content does not overflow container).
- Allows use of a custom string instead of an ellipsis.
## Usage
## Limitations
> [**Editable demo (CodePen)**](https://codepen.io/lyuanqing/pen/VQQVry)
- Requires some [CSS to be set on the DOM element and its parent](#css). In particular, the DOM element must have an explicitly set `line-height` in pixels.
- Truncation is in pure JavaScript; does *not* use [`-webkit-line-clamp`](https://css-tricks.com/line-clampin/).
- Assumes that the text to be truncated does *not* contain any inline HTML tags (eg. `em`, `strong`, etc.).
HTML:
## Usage
#### HTML
```html
<div class="line-clamp-wrapper">
<div class="line-clamp">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
<div class="line-clamp">
Lorem ipsum dolor sit amet, <strong>consectetur adipiscing</strong> elit.
</div>
```
#### CSS
CSS:
```css
.line-clamp-wrapper {
height: 60px;
overflow: hidden;
}
.line-clamp {
width: 100px;
line-height: 20px;
overflow-wrap: break-word;
word-wrap: break-word;
}
```
#### JavaScript
JavaScript:
```js
import lineClamp from 'line-clamp';
const element = document.querySelector('.line-clamp')
lineClamp(element, 3)
```
lineClamp(element, { lineCount: 3 });
Boom:
```html
<div class="line-clamp" style="overflow: hidden; overflow-wrap: break-word; word-wrap: break-word;">
Lorem ipsum dolor sit amet, <strong>consectetur…</strong>
</div>
```
## Example
### Limitations
To run the [example](example), do:
- The element is assumed to have a pixel line-height, obtained via [`window.getComputedStyle`](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle).
```
$ git clone https://github.com/yuanqing/line-clamp
$ npm install
$ npm install --global gulp
$ gulp example --open
```
## API
```js
import lineClamp from 'line-clamp';
const lineClamp = require('line-clamp')
```
### lineClamp(element, options)
### lineClamp(element, lineCount [, options])
- `element` &mdash; A DOM element.
`options` is an optional object literal.
- `options` &mdash; An object literal:
- Set `options.ellipsis` to change the string to be appended to the truncated text (defaults to `…`).
Key | Description | Default
:--|:--|:--
`ellipsisCharacter` | The string to append to the truncated text. | `\u2026`
`lineCount` | *Required.* The number of lines to show. | `undefined`
See [Usage](#usage).
See [Usage](#usage) above for the accompanying CSS.
## Installation
Install via [npm](https://npmjs.com):
Install via [yarn](https://yarnpkg.com):
```sh
$ yarn add line-clamp
```
$ npm i --save line-clamp
Or [npm](https://npmjs.com):
```sh
$ npm install --save line-clamp
```

@@ -86,0 +77,0 @@

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (element) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
lineCount = _ref.lineCount,
ellipsisCharacter = _ref.ellipsisCharacter;
// Read the `line-height` of `element`, and use it to compute the height of
// `element` required to fit the given `lineCount`.
var lineHeight = parseInt(window.getComputedStyle(element).lineHeight, 10);
var maximumHeight = lineCount * lineHeight;
// Exit if text does not overflow the `element`.
if (element.scrollHeight <= maximumHeight) {
return;
}
truncateByWord(element, maximumHeight);
truncateByCharacter(element, maximumHeight, ellipsisCharacter || ELLIPSIS);
};
var ELLIPSIS = '\u2026';
var WHITESPACE_REGEX = /(?=\s)/;
var TRAILING_WHITESPACE_REGEX = /\s+$/;
// Truncate the text of `element` such that it does not exceed the
// `maximumHeight`. Return `true` if we need to truncate by character, else
// return `false`.
function truncateByWord(element, maximumHeight) {
var innerHTML = element.innerHTML;
// Split the text of `element` by whitespace.
var chunks = innerHTML.split(WHITESPACE_REGEX);
// The text does not contain whitespace; we need to attempt to truncate
// by character.
if (chunks.length === 1) {
return true;
}
// Loop over the chunks, and try to fit more chunks into the `element`.
var i = -1;
var length = chunks.length;
var newInnerHTML = '';
while (++i < length) {
newInnerHTML += chunks[i];
element.innerHTML = newInnerHTML;
// If the new height now exceeds the `maximumHeight` (where it did not
// in the previous iteration), we know that we are at most one line
// over the optimal text length.
if (element.offsetHeight > maximumHeight) {
return true;
}
}
return false;
}
// Append `ellipsisCharacter` to `element`, trimming off trailing characters
// in `element` such that `element` will not exceed the `maximumHeight`.
function truncateByCharacter(element, maximumHeight, ellipsisCharacter) {
var innerHTML = element.innerHTML;
var length = innerHTML.length;
// In each iteration, we trim off one trailing character . Also trim
// off any trailing punctuation before appending the `ellipsisCharacter`.
while (length > 0) {
element.innerHTML = innerHTML.substring(0, length).replace(TRAILING_WHITESPACE_REGEX, '') + ellipsisCharacter;
if (element.offsetHeight <= maximumHeight) {
return;
}
length--;
}
}
const ELLIPSIS = '\u2026';
const WHITESPACE_REGEX = /(?=\s)/;
const TRAILING_WHITESPACE_REGEX = /\s+$/;
// Truncate the text of `element` such that it does not exceed the
// `maximumHeight`. Return `true` if we need to truncate by character, else
// return `false`.
function truncateByWord(element, maximumHeight) {
const innerHTML = element.innerHTML;
// Split the text of `element` by whitespace.
let chunks = innerHTML.split(WHITESPACE_REGEX);
// The text does not contain whitespace; we need to attempt to truncate
// by character.
if (chunks.length === 1) {
return true;
}
// Loop over the chunks, and try to fit more chunks into the `element`.
let i = -1;
const length = chunks.length;
let newInnerHTML = '';
while (++i < length) {
newInnerHTML += chunks[i];
element.innerHTML = newInnerHTML;
// If the new height now exceeds the `maximumHeight` (where it did not
// in the previous iteration), we know that we are at most one line
// over the optimal text length.
if (element.offsetHeight > maximumHeight) {
return true;
}
}
return false;
}
// Append `ellipsisCharacter` to `element`, trimming off trailing characters
// in `element` such that `element` will not exceed the `maximumHeight`.
function truncateByCharacter(element, maximumHeight, ellipsisCharacter) {
const innerHTML = element.innerHTML;
let length = innerHTML.length;
// In each iteration, we trim off one trailing character . Also trim
// off any trailing punctuation before appending the `ellipsisCharacter`.
while (length > 0) {
element.innerHTML = innerHTML.substring(0, length).replace(TRAILING_WHITESPACE_REGEX, '') + ellipsisCharacter;
if (element.offsetHeight <= maximumHeight) {
return;
}
length--;
}
}
export default function(element, { lineCount, ellipsisCharacter } = {}) {
// Read the `line-height` of `element`, and use it to compute the height of
// `element` required to fit the given `lineCount`.
const lineHeight = parseInt(window.getComputedStyle(element).lineHeight, 10);
const maximumHeight = lineCount * lineHeight;
// Exit if text does not overflow the `element`.
if (element.scrollHeight <= maximumHeight) {
return;
}
truncateByWord(element, maximumHeight);
truncateByCharacter(element, maximumHeight, ellipsisCharacter || ELLIPSIS);
}