Giter VIP home page Giter VIP logo

shave's Introduction

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

This software is maintained under a new repository located at yowainwright/shave

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️


Shave


npm Bower Travis Greenkeeper CDNJS Twitter share


Shave ✁

Shave is a zero dependency javascript plugin that truncates multi-line text to fit within an html element based on a set pixel number max-height. It then stores the diff of the original text string in a hidden <span> element following the visible text. This means the original text remains intact!

Shave, compared to other truncation plugins:

  • maintains the original text after truncation.
  • does not require other libraries
  • only requires a selector and a max height
  • is very lightweight; ~1.5kb unminified
  • allows for custom ellipsis strings and class names but doesn't over complicate
  • is fast and capable of truncating text within lots of elements quickly
  • is additive. It will play nice with other javascript libraries and more truncation features can easily be built with it.
  • supports non-spaced languages (Non-ascii).

Installing from a package manager

npm

npm install shave --save

bower

bower install shave --save

yarn

yarn add shave

Usage

Add dist/shave.js to your html

  • Or, dist/jquery.shave.js for jQuery/Zepto as of Shave >= v2.

Or as a module

import shave from 'shave';

Syntax

Basic setup

shave('selector', maxheight);
// shave('.shave-selector', 0) for example

Shave also provided options only to overwrite what it uses.

If you'd like have custom class names and not use .js-shave:

shave('selector', maxheight, { classname: 'classname' });

Or if you'd like to have custom characters (instead of the standard ellipsis):

shave('selector', maxheight, { character: '✁' });

Or both:

shave('selector', maxheight, { classname: 'classname', character: '✁' });

Without spaces:

shave('selector', maxheight, { spaces: false });

You can also use shave as a jQuery or Zepto plugin. As of Shave >= v2, use dist/jquery.shave.js for jQuery/Zepto.

$('selector').shave(maxheight);

And here's a jQuery/Zepto example with custom options:

$('selector').shave(maxheight, { classname: 'your-css-class', character: '✁'  });

If you're using a non-spaced language, you can support shave by setting an option spaces to false.

$('selector').shave(maxheight, { classname: 'your-css-class', character: '✁', spaces: false });

Examples

Codepen example with plain javascript.

Codepen example with jQuery.

Codepen example with a non-spaced language.

Notes

text-overflow: ellipsis is the way to go when truncating text to a single line. Shave does something very similar to text-overflow: ellipsis but for multiple lines when line-clamp is not supported. Shave bypasses being a line-clamp polyfill by only accepting a max-height number. This keeps shave a fast and light weight utility.

Shave implements a binary search to truncate text in the most optimal way possible.

Shave is meant to truncate text within a selected html element. This means it will overwrite html within an html element with just the text within the selected element.

Here are some super basic examples of shave with window resize and click events. 🙌

Shave works in all modern browsers and was tested in some not so modern browsers (like Internet Explorer 8) - it works there too. 🍻


Created and maintained by Jeff Wainwright with Dollar Shave Club Engineering.

shave's People

Contributors

awcross avatar briangonzalez avatar danyfoo avatar demiazz avatar digitalcraft avatar garygreen avatar greenkeeper[bot] avatar jackrugile avatar jakiestfu avatar malko42 avatar mattsacks avatar pvnr0082t avatar pwfisher avatar renovate[bot] avatar seth-globant avatar snaptopixel avatar ursm avatar yowainwright avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shave's Issues

License mismatch

You have different license in package.json/bower.json (ISC) and in LICENSE (MIT) file.

Expose "done" callback

It would be nice to have a callback to use to trigger an action once Shave finished to do its work.

It could be useful to hide the text with opacity: 0 while the library is doing its work and show it once it finished.

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Replaced the old Node.js version in your .nvmrc with the new one

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Unshave support.

It'll be better if shave( /* ... */ ) provides a decent way to restore everything to it's origin.
Now, I have to set the innerHTML to it's original text. Sometimes I am not sure about what it was before.

Maybe like shave( /* ... */ ) returns a function, and we call it to reset everything.

Give minified version and also include the current version in shave.js

First of all awesome tool! I compared the execution time of a big page on an actual project.

With trunk8 it was ~550ms and with shave it ist ~6ms. Really awesome!

But as the title says. It would be awesome if you could add the version number to the js file and also add add a minified version. Also if it's not really needed. But saving additional space it not bad ;)

Removes end of line in IE11

(This may be by design, so if it is, apologies in advance.)

I work somewhere where I can't install anything on my work PC, so I'm using Shave in the browser (IE 11). When I call it on some HTML that has line breaks (<br /> or <br>) it removes the line breaks when truncating (or maybe just doesn't apply them).

For example, this is the text before truncating:
capture

and this is the same text after calling Shave on it:
capture

I'm running Shave on a Windows 7 x86 machine in IE 11. Unfortunately we're not allowed to install new programs so I can't test it in any other browsers. Here's my HTML:

<div id="parent">

<div id="child" class="divClass">
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
This is a lot of text that should get truncated so let's see if it works.<br><br>
</div>

</div>

<script src="shave.js"></script>

<script>

shave('#child', 35, {character: '...'});

</script>

Even after increasing the max height it still keeps going on the same line.

As a side note, Shave is a great plugin. Very impressed with it. Let me know if you want any more info.

Website example paragraph gets shorter and shorter on multiple clicks.

Hi there, thanks for a great plugin! I noticed a bug on the website example. If you keep clicking on Truncate Text / Reset button, then the paragraph will get shorter and shorter. In the end you end up with Shave is a zero dependency javascriptthethe originaltact!. It's pretty easy to replicate.

Option to use current height as desired height

In a CMS setting, the font size of various elements can be dynamic. It would be useful if there would be an option to use the current height of an element as the max-height. Or even better, if it could use the desired number of lines to figure it out.

1 word missing (Plain javascript codepen)

Hi,

I was trying the plain javascript demo, linked on your website. Looking at the dom inspector... I see there is one word ("hendrerit") missing between the displayed text (ends with justo) and the hidden section (starts with quis)... (justo hendrerit quis)

Sander

IE Compatibility

Hi,

First of all it's a nice plugin 👏

Is it possible for you to add compatibility informations ?

Text is truncated even though there's enough height to fit

Text was getting truncated even though there's enough height to fit all text. This happens when offsetHeight is exactly equal to maxHeight. On line 43 of shave.js, the comparison should be less than or equal to. I was forced to add an extra pixel to not get my text truncated enough though there's enough space.

Simple solution for toggling?

Is there a simple way to toggle the shave (like some kind of "unshave") with a class or something? I simply want the text to be "shaved" on page load and then "unshaved" by clicking on the whole text (or some button). I'm using jQuery. Thx in advance!

Better support for resizing

The example given on code pen works ok when you have one element to resize, but doesn't scale to having multiple elements very easily.

There's function to "reset" the element back to how it was and there's no option to pass an object instead of a selector to the element. This makes it difficult to optimize truncating multiple elements on window resize. If we need to go through each element, reset them manually and then search for all those elements a second time, it's a lot slower than being able to pass the element directly.

Why not make shaveEl public?

Events

Hi,

Awesome package!
Can you please think to add (or to provide guidance) about what dotdotdot is providing (super useful):

dot-resize-update - automatically update if window resize event occurs. It's equivalent to option watch:'window'.

dot-timer-update - automatically update if window resize event occurs. It's equivalent to option watch:true.

dot-load-update - automatically update after the window has beem completely rendered. Can be useful if your content is generated dynamically using JS and, hence, jQuery.dotdotdot can't correctly detect the height of the element before it's rendered completely.

Cheers

Support for custom toggle / show more button

I've created a custom version of shave and added some html and a +84 to some calculation and got a working solution for a custom show more button.

I guess we can implement this as option.

/**
  shave - Shave is a javascript plugin that truncates multi-line text within a html element based on set max height
  @version v2.4.0
  @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 (!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 = "<div class=\"js-shave-char\"><div class=\"js-shave-char-inner\">".concat(character, "</div><br><div class=\"button action primary negative\">Show more</div></div>");
    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+84)) max = spaces ? pivot - 1 : pivot - 2;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);
      el.insertAdjacentHTML('beforeend', "<span class=\"".concat(classname, "\" style=\"display:none;\">").concat(diff, "</span>"));
      styles.height = heightStyle;
      styles.maxHeight = maxHeightStyle;
    }
  }

```

Problems with the spaces option

Hello, I have encountered the following strange behavior when trying to shave an english text while preserving whole words (instead of splitting on any letter) in the following releases:

2.0.4: Defaults to splitting on any letter. Passing {spaces: true} makes it split on spaces. Probably the closest to what I would expect to happen.
2.1.2: spaces option has no effect at all(likely because of #98). Changing the source to spaces = false makes it split on spaces (the opposite of 2.0.4? seems odd considering the default was changed in this version and at odds with the use for non-spaced languages)
2.2.0 and 2.2.1: spaces option has no effect at all
The version that is in the codepen demos (says 2.2.0 but I'm not so sure it actually matches that release): Works like 2.1.2, but you can actually pass in {spaces: false} without editing the source.

Additionally, when splitting on spaces the space itself is removed (this differs from the behavior when splitting on any character, where spaces are always preserved). It would be nice if the space that was split on could be kept in the hidden span to make it easier to implement a button to show/hide the rest of the text.

Use scrollHeight instead of offsetHeight

If the text you want to truncate is a child of a parent who's height you use as the maxHeight, then shave will won't truncate. The offsetHeight will equal the maxHeight, because the overflowing text doesn't affect offsetHeight. If offsetHeight is replaced by scrollHeight, this fixes the problem, and doesn't break any existing use cases that I'm aware of

This also fixed a very quirky bug potentially related to flexbox and/or React where offsetHeight was not updating as text was being truncated. It's quite difficult to reproduce, but I could try if necessary.

I'm happy to submit a PR

IE 8 broken when no text content

Hi there,

I used shave and got some trouble like below imgs:

image

image

I think the problem is I shave a empty <div/>.

Update:
The problem is IE8 do not have el.textContent. Can use el.innerText as fallback.

Truncate text in the middle

At my current project we need for dots to appear in the middle of text instead of end of text. Could you please add this feature? It would be great if this library had option where you want dots to appear(at the begging of text, at the end, in the middle).

Big blob in repo / big repository size

Currently the repository is about 30 MB big.

$ java -jar bfg-1.13.0.jar --strip-blobs-bigger-than 10M shave-extended/

Using repo : C:\Users\Daniel\github\shave-extended\.git

Scanning packfile for large blobs: 16417
Scanning packfile for large blobs completed in 229 ms.
Found 1 blob ids for large blobs - biggest=45020592 smallest=45020592
Total size (unpacked)=45020592
Found 31 objects to protect
Found 5 tag-pointing refs : refs/tags/v0.0.2, refs/tags/v0.0.3, refs/tags/v0.0.4, ...
Found 42 commit-pointing refs : HEAD, refs/heads/master, refs/remotes/origin/HEAD, ...

Protected commits
-----------------

These are your protected commits, and so their contents will NOT be altered:

 * commit 05dd580f (protected by 'HEAD')

Cleaning
--------

Found 200 commits
Cleaning commits:       100% (200/200)
Cleaning commits completed in 1.091 ms.

Updating 5 Refs
---------------

        Ref                Before     After
        --------------------------------------
        refs/tags/v0.0.2 | 03a3437e | c4dfed2a
        refs/tags/v0.0.3 | 463a7bca | 29c046f6
        refs/tags/v0.0.4 | 5af4fdc2 | f095289b
        refs/tags/v0.0.5 | afb0e46d | ec6c79e9
        refs/tags/v0.0.6 | bb6bf43c | 5e855367

Updating references:    100% (5/5)
...Ref update completed in 145 ms.

Commit Tree-Dirt History
------------------------

        Earliest                                              Latest
        |                                                          |
        DDmmmmm.....................................................

        D = dirty commits (file tree fixed)
        m = modified commits (commit message or parents changed)
        . = clean commits (no changes to file tree)

                                Before     After
        -------------------------------------------
        First modified commit | 7a9950ff | 350d12a7
        Last dirty commit     | 68d48dfb | 533078af

Deleted files
-------------

        Filename    Git id
        ------------------------------
        phantomjs | 36204c5f (42,9 MB)


In total, 34 object ids were changed. Full details are logged here:

        C:\Users\Daniel\github\shave-extended.bfg-report\2018-09-05\22-44-19

BFG run is complete! When ready, run: git reflog expire --expire=now --all && git gc --prune=now --aggressive

Set element's max-height to avoid reflow

Changing the original element's height would cause the browser to reflow, in a very very long page, this might be a performance issue, what about setting element's max-height before the binary search, and using scrollHeight or creating a detached element with an absolute position?

Possibility to support Typescript in the future?

What Is the issue?

I'm trying to use this library on my project of Angular 6.x, but since Angular 2.x is using typescript, i can't not use this plugin because it has no definition typescript file (d.ts) to reference its methods in typescript projects.

What can I do to support this library as non typescript library in my project?

destructuring & parameters

HI. Just an input about code simplification.

As you are using ES6, you could define your function like:

export default function shave(target, maxHeight, { character = '…', classname = 'js-shave', spaces = true } = {})

instead of all the default object soup.

Not quite working with React... I mean, feature request...

I am having trouble using shave with React. I realize this might be out of it's scope, but it would be fantastic if it could be used well with it.

The following things I've tried unsuccessfully:

1. Shaving a div with text components

<div className="to-be-shaved">
    <h3>Title</h3>
    <p>Some text... bla bla bla</p>
    <p>More text... bla bla bla</p>
</div>

2. Shaving a div with html set with dangerouslySetInnerHTLML

<div className="to-be-shaved" dangerouslySetInnerHTML={{ __html: stringWithHTML }}>
</div>

3. Shaving a div with html parsed with react-html-parser (Same thing as 1., but worth a try...)

<div className="to-be-shaved">
     { ReactHtmlParses(stringWithHTML) }
</div>

result: In all of these, it shaves but all formatting and line breaks are gone.

Support for ex and other units

What Is the issue?

It seems currently we can not use ex and other units to set the desired height.

Provide issue context below using code examples, images, or links


Read about references issues here. Provide paragraph text responses to each header.

types missing when installing from npm

What Is the issue?

I see types in the repo but they don't end up in the node_modules folder when installing via yarn

Provide issue context below using code examples, images, or links

If I yarn install dollarshaveclub/shave I get all the files

Possible to pass a DOM node instead of a selector?

We have an instance where we need to set different max heights for each instance of an element. i guess this could be done with jQuery using each, but can it be done using vanilla JS? I'm guessing querySelectorAll gets called from the argument.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.