├── .gitignore
├── .travis.yml
├── src
├── index.js
└── directive.js
├── rollup.config.js
├── LICENSE
├── README.md
├── package.json
├── examples
└── index.html
└── vue-clampy.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | branches:
3 | only:
4 | - master
5 | - /^greenkeeper/.*$/
6 | cache:
7 | yarn: true
8 | directories:
9 | - node_modules
10 | notifications:
11 | email: false
12 | node_js:
13 | - '9.5'
14 | before_script:
15 | - npm prune
16 | script:
17 | - npm run build
18 | after_success:
19 | - npm run semantic-release
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import VueClampy from './directive';
2 | import { setDefaults } from './directive';
3 |
4 | const install = function(Vue, options) {
5 | if (options) setDefaults(options);
6 | Vue.directive('clampy', VueClampy);
7 | Vue.prototype.$clampy = VueClampy.clampy;
8 | };
9 |
10 | if (typeof window !== 'undefined' && window.Vue) {
11 | window.VueClampy = VueClampy;
12 | window.VueClampy.setDefaults = setDefaults;
13 | Vue.use(install);
14 | }
15 |
16 | VueClampy.install = install;
17 | export default VueClampy;
18 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import resolve from 'rollup-plugin-node-resolve'
3 | import commonjs from 'rollup-plugin-commonjs'
4 |
5 | export default {
6 | entry: './src/index.js',
7 | dest: 'vue-clampy.js',
8 |
9 | plugins: [
10 | resolve(),
11 | commonjs(),
12 | babel({
13 | exclude: 'node_modules/**',
14 | presets: ['es2015-rollup'],
15 | plugins: ['transform-object-assign']
16 | })
17 | ],
18 |
19 | format: 'umd',
20 | moduleName: 'vue-clampy'
21 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Alexandre Moore
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-clampy
2 | [](https://travis-ci.org/clampy-js/vue-clampy)
3 | [](https://github.com/clampy-js/vue-clampy/issues)
4 | [](https://github.com/clampy-js/vue-clampy/blob/master/LICENSE)
5 | [](https://www.npmjs.com/package/@clampy-js/vue-clampy)
6 |
7 | Vue.js (2+) directive that clamps the content of an element by adding an ellipsis to it if the content inside is too long.
8 |
9 | It uses [@clampy-js/clampy](https://github.com/clampy-js/clampy) library (a fork of [Clamp.js](https://github.com/josephschmitt/Clamp.js)) behind the scene to apply the ellipsis.
10 |
11 | It automatically re-clamps itself when the element or the browser window change size.
12 |
13 | #### Installation
14 | You can install @clampy-js/vue-clampy using NPM or Yarn:
15 |
16 | ```
17 | npm install @clampy-js/vue-clampy
18 | ```
19 |
20 | ```
21 | yarn install @clampy-js/vue-clampy
22 | ```
23 |
24 | #### Usage
25 | ```typescript
26 |
39 |
40 | Long text to clamp here
41 |
42 | ```
43 |
44 | #### Options
45 | You can also override default options globally:
46 |
47 | ```typescript
48 |
49 | Vue.use(clampy, {
50 | truncationChar: '✂️'
51 | });
52 |
53 | ```
54 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@clampy-js/vue-clampy",
3 | "description": "Vue.js (2+) directive that clamps the content of an element by adding an ellipsis to it if the content inside is too long.",
4 | "version": "0.0.0-development",
5 | "author": "Alexandre Moore ",
6 | "bugs": {
7 | "url": "https://github.com/clampy-js/vue-clampy/issues"
8 | },
9 | "dependencies": {
10 | "vue": "^2.0.0",
11 | "@clampy-js/clampy": "^1.0.9"
12 | },
13 | "devDependencies": {
14 | "babel-plugin-transform-object-assign": "^6.22.0",
15 | "babel-preset-es2015-rollup": "^3.0.0",
16 | "lint-staged": "^3.3.1",
17 | "pre-commit": "^1.2.2",
18 | "prettier": "^0.19.0",
19 | "rollup": "^0.41.6",
20 | "rollup-plugin-babel": "^2.7.1",
21 | "rollup-plugin-commonjs": "^8.0.2",
22 | "rollup-plugin-node-resolve": "^2.0.0",
23 | "semantic-release": "^15.5.0",
24 | "travis-deploy-once": "^5.0.0"
25 | },
26 | "peerDependencies": {
27 | "vue": "^2.0.0"
28 | },
29 | "files": [
30 | "vue-clampy.js"
31 | ],
32 | "homepage": "https://github.com/clampy-js/vue-clampy",
33 | "keywords": [
34 | "clamp",
35 | "ellipsis",
36 | "clampy-js",
37 | "clampy",
38 | "vue",
39 | "vue-directive",
40 | "vuejs"
41 | ],
42 | "license": "MIT",
43 | "main": "vue-clampy.js",
44 | "repository": {
45 | "type": "git",
46 | "url": "https://github.com/clampy-js/vue-clampy"
47 | },
48 | "scripts": {
49 | "test": "echo \"Error: no test specified\" && exit 1",
50 | "build": "rollup -c",
51 | "semantic-release": "semantic-release",
52 | "travis-deploy-once": "travis-deploy-once"
53 | },
54 | "publishConfig": {
55 | "access": "public"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Examples for vue-clampy
7 |
8 |
9 |
20 |
21 |
22 |
23 |
24 |
25 |
Unclamped content
26 |
27 |
{{originalContent}}
28 |
29 |
30 |
31 | Clamped content (clampy="{{clampyValue}}")
32 |
33 |
34 |
35 |
36 |
{{originalContent}}
37 |
38 |
39 |
40 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/directive.js:
--------------------------------------------------------------------------------
1 | import * as clampy_ from '@clampy-js/clampy/dist/clampy.umd.js';
2 | // import * as elementResizeDetectorMaker_ from 'element-resize-detector';
3 |
4 | // https://github.com/rollup/rollup/issues/670#issuecomment-284621537
5 | const clampy = clampy_.default || clampy_;
6 | // const elementResizeDetectorMaker = (elementResizeDetectorMaker_).default || elementResizeDetectorMaker_;
7 |
8 | // const resizeDetector = elementResizeDetectorMaker({ strategy: 'scroll' });
9 | var clampValue;
10 |
11 | var _extends = Object.assign ||
12 | function(target) {
13 | for (var i = 1; i < arguments.length; i++) {
14 | var source = arguments[i];
15 |
16 | for (var key in source) {
17 | if (Object.prototype.hasOwnProperty.call(source, key)) {
18 | target[key] = source[key];
19 | }
20 | }
21 | }
22 |
23 | return target;
24 | };
25 |
26 | var defaults = {
27 | clamp: 'auto',
28 | truncationChar: '…',
29 | splitOnChars: ['.', '-', '–', '—', ' '],
30 | useNativeClamp: false
31 | };
32 |
33 | export function setDefaults(options) {
34 | defaults = _extends({}, defaults, options);
35 | }
36 |
37 | function setup(el, clampValue) {
38 | tearDown(el);
39 |
40 | const resizeListener = () => {
41 | clampElement(el, clampValue);
42 | };
43 |
44 | el.__VueClampy = {
45 | clampValue,
46 | resizeListener
47 | };
48 |
49 | // Re-clamp on element resize
50 | // resizeDetector.listenTo(el, () => {
51 | // clampElement(el, clampValue);
52 | // });
53 |
54 | // Also re-clamp on window resize
55 | window.addEventListener('resize', resizeListener);
56 |
57 | clampElement(el, clampValue);
58 | }
59 |
60 | function tearDown(el) {
61 | if (!el || !el.__VueClampy) return;
62 | // Remove all listeners
63 | // resizeDetector.removeAllListeners(el);
64 | window.removeEventListener('resize', el.__VueClampy.resizeListener);
65 | }
66 |
67 | function setInitialContent(el) {
68 | if (el.clampInitialContent === undefined) {
69 | el.clampInitialContent = el.innerHTML.trim();
70 | }
71 | }
72 |
73 | function clampElement(el, clamp) {
74 | // We use element-resize-detector to trigger the ellipsis.
75 | // Element-resize-detector adds an inner div to monitor
76 | // it's scroll events.
77 | // The process of truncating the text for ellipsis removes this div, so we need to remove and readd it
78 | const scrollNode = el.querySelector('.erd_scroll_detection_container');
79 | if (scrollNode) {
80 | el.removeChild(scrollNode);
81 | }
82 |
83 | setInitialContent(el);
84 |
85 | if (el.clampInitialContent !== undefined) {
86 | el.innerHTML = el.clampInitialContent;
87 | }
88 |
89 | defaults = _extends({}, defaults, { clamp: clamp ? clamp : 'auto' });
90 |
91 | // Set the opacity to 0 to avoid content to flick when clamping.
92 | el.style.opacity = '0';
93 | const result = clampy.clamp(el, defaults);
94 |
95 | // Set the opacity back to 1 now that the content is clamped.
96 | el.style.opacity = '1';
97 |
98 | if (scrollNode) {
99 | el.appendChild(scrollNode);
100 | }
101 | }
102 |
103 | export default {
104 | inserted(el, binding, vnode) {
105 | clampValue = binding.value;
106 | setup(el, clampValue);
107 | },
108 |
109 | update(el, binding, vnode) {
110 | clampValue = binding.value;
111 | setup(el, clampValue);
112 | },
113 |
114 | unbind(el, binding, vnode) {
115 | tearDown(el);
116 | delete el.__VueClampy;
117 | }
118 | };
119 |
--------------------------------------------------------------------------------
/vue-clampy.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 | typeof define === 'function' && define.amd ? define(factory) :
4 | (global['vue-clampy'] = factory());
5 | }(this, (function () { 'use strict';
6 |
7 | var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8 |
9 |
10 |
11 | function unwrapExports (x) {
12 | return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
13 | }
14 |
15 | function createCommonjsModule(fn, module) {
16 | return module = { exports: {} }, fn(module, module.exports), module.exports;
17 | }
18 |
19 | var clampy_umd = createCommonjsModule(function (module, exports) {
20 | (function (global, factory) {
21 | factory(exports);
22 | }(commonjsGlobal, (function (exports) { 'use strict';
23 |
24 | var ClampOptions = /** @class */ (function () {
25 | function ClampOptions(clamp, truncationChar, truncationHTML, splitOnChars) {
26 | this.clamp = clamp || "auto";
27 | this.truncationChar = truncationChar || "…";
28 | this.truncationHTML = truncationHTML;
29 | this.splitOnChars = splitOnChars || [".", "-", "–", "—", " "];
30 | }
31 | return ClampOptions;
32 | }());
33 | var ClampResponse = /** @class */ (function () {
34 | function ClampResponse(original, clamped) {
35 | this.original = original;
36 | this.clamped = clamped;
37 | }
38 | return ClampResponse;
39 | }());
40 | /**
41 | * Clamps (ie. cuts off) an HTML element's content by adding ellipsis to it if the content inside is too long.
42 | *
43 | * @export
44 | * @param {HTMLElement} element The HTMLElement that should be clamped.
45 | * @param {ClampOptions} [options] The Clamp options
46 | * @returns {ClampResponse} The Clamp response
47 | */
48 | function clamp(element, options) {
49 | var win = window;
50 | if (!options) {
51 | options = {
52 | clamp: "auto",
53 | truncationChar: "…",
54 | splitOnChars: [".", "-", "–", "—", " "]
55 | };
56 | }
57 | var opt = {
58 | clamp: options.clamp || "auto",
59 | splitOnChars: options.splitOnChars || [".", "-", "–", "—", " "],
60 | truncationChar: options.truncationChar || "…",
61 | truncationHTML: options.truncationHTML
62 | };
63 | var splitOnChars = opt.splitOnChars.slice(0);
64 | var splitChar = splitOnChars[0];
65 | var chunks;
66 | var lastChunk;
67 | var sty = element.style;
68 | var originalText = element.innerHTML;
69 | var clampValue = opt.clamp;
70 | var isCSSValue = clampValue.indexOf && (clampValue.indexOf("px") > -1 || clampValue.indexOf("em") > -1);
71 | var truncationHTMLContainer;
72 | if (opt.truncationHTML) {
73 | truncationHTMLContainer = document.createElement("span");
74 | truncationHTMLContainer.innerHTML = opt.truncationHTML;
75 | }
76 | // UTILITY FUNCTIONS __________________________________________________________
77 | /**
78 | * Return the current style for an element.
79 | * @param {HTMLElement} elem The element to compute.
80 | * @param {string} prop The style property.
81 | * @returns {number}
82 | */
83 | function computeStyle(elem, prop) {
84 | return win.getComputedStyle(elem).getPropertyValue(prop);
85 | }
86 | /**
87 | * Returns the maximum number of lines of text that should be rendered based
88 | * on the current height of the element and the line-height of the text.
89 | */
90 | function getMaxLines(height) {
91 | var availHeight = height || element.clientHeight;
92 | var lineHeight = getLineHeight(element);
93 | return Math.max(Math.floor(availHeight / lineHeight), 0);
94 | }
95 | /**
96 | * Returns the maximum height a given element should have based on the line-
97 | * height of the text and the given clamp value.
98 | */
99 | function getMaxHeight(clmp) {
100 | var lineHeight = getLineHeight(element);
101 | return lineHeight * clmp;
102 | }
103 | /**
104 | * Returns the line-height of an element as an integer.
105 | */
106 | function getLineHeight(elem) {
107 | var lh = computeStyle(elem, "line-height");
108 | if (lh === "normal") {
109 | // Normal line heights vary from browser to browser. The spec recommends
110 | // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff.
111 | lh = parseFloat(parseFloat(computeStyle(elem, "font-size")).toFixed(0)) * 1.1;
112 | }
113 | return parseFloat(parseFloat(lh).toFixed(0));
114 | }
115 | /**
116 | * Returns the height of an element as an integer (max of scroll/offset/client).
117 | * Note: inline elements return 0 for scrollHeight and clientHeight
118 | */
119 | function getElemHeight(elem) {
120 | // The '- 4' is a hack to deal with the element height when the browser(especially IE) zoom level is not 100%.
121 | // It also doesn't impact clamping when the browser zoom level is 100%.
122 | return Math.max(elem.scrollHeight, elem.clientHeight) - 4;
123 | }
124 | /**
125 | * Gets an element's last child. That may be another node or a node's contents.
126 | */
127 | function getLastChild(elem) {
128 | if (!elem.lastChild) {
129 | return;
130 | }
131 | // Current element has children, need to go deeper and get last child as a text node
132 | if (elem.lastChild.children && elem.lastChild.children.length > 0) {
133 | return getLastChild(Array.prototype.slice.call(elem.children).pop());
134 | }
135 | // This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying
136 | else if (!elem.lastChild ||
137 | !elem.lastChild.nodeValue ||
138 | elem.lastChild.nodeValue === "" ||
139 | elem.lastChild.nodeValue === opt.truncationChar) {
140 | if (!elem.lastChild.nodeValue) {
141 | // Check for void/empty element (such as
tag) or if it's the ellipsis and remove it.
142 | if ((elem.lastChild.firstChild === null ||
143 | elem.lastChild.firstChild.nodeValue === opt.truncationChar) &&
144 | elem.lastChild.parentNode) {
145 | elem.lastChild.parentNode.removeChild(elem.lastChild);
146 | // Check if the element has no more children and remove it if it's the case.
147 | // This can happen for instance with lists (i.e. and ) with no items.
148 | if ((!elem.children || elem.children.length === 0) && elem.parentNode) {
149 | elem.parentNode.removeChild(elem);
150 | return getLastChild(element);
151 | }
152 | }
153 | // Check if it's a text node
154 | if (elem.lastChild.nodeType === 3) {
155 | return elem.lastChild;
156 | }
157 | else {
158 | return getLastChild(elem.lastChild);
159 | }
160 | }
161 | if (elem.lastChild &&
162 | elem.lastChild.parentNode &&
163 | elem.lastChild.nodeValue === opt.truncationChar) {
164 | elem.lastChild.parentNode.removeChild(elem.lastChild);
165 | }
166 | else {
167 | return elem;
168 | }
169 | return getLastChild(element);
170 | }
171 | // This is the last child we want, return it
172 | else {
173 | return elem.lastChild;
174 | }
175 | }
176 | /**
177 | * Apply the ellipsis to the element
178 | * @param elem the element to apply the ellipsis on
179 | * @param str The string that will be set to the element
180 | */
181 | function applyEllipsis(elem, str) {
182 | elem.nodeValue = str + opt.truncationChar;
183 | }
184 | /**
185 | * Removes one character at a time from the text until its width or
186 | * height is beneath the passed-in max param.
187 | */
188 | function truncate(target, maxHeight) {
189 | /**
190 | * Resets global variables.
191 | */
192 | function reset() {
193 | splitOnChars = opt.splitOnChars.slice(0);
194 | splitChar = splitOnChars[0];
195 | chunks = null;
196 | lastChunk = null;
197 | }
198 | if (!target || !maxHeight || !target.nodeValue) {
199 | return;
200 | }
201 | var nodeValue = target.nodeValue.replace(opt.truncationChar, "");
202 | // Grab the next chunks
203 | if (!chunks) {
204 | // If there are more characters to try, grab the next one
205 | if (splitOnChars.length > 0) {
206 | splitChar = splitOnChars.shift();
207 | }
208 | else {
209 | // No characters to chunk by. Go character-by-character
210 | splitChar = "";
211 | }
212 | chunks = nodeValue.split(splitChar);
213 | }
214 | // If there are chunks left to remove, remove the last one and see if
215 | // the nodeValue fits.
216 | if (chunks.length > 1) {
217 | lastChunk = chunks.pop();
218 | applyEllipsis(target, chunks.join(splitChar));
219 | }
220 | else {
221 | // No more chunks can be removed using this character
222 | chunks = null;
223 | }
224 | // Insert the custom HTML before the truncation character
225 | if (truncationHTMLContainer) {
226 | target.nodeValue = target.nodeValue.replace(opt.truncationChar, "");
227 | element.innerHTML =
228 | target.nodeValue + " " + truncationHTMLContainer.innerHTML + opt.truncationChar;
229 | }
230 | // Search produced valid chunks
231 | if (chunks) {
232 | // It fits
233 | if (element.clientHeight <= maxHeight) {
234 | // There's still more characters to try splitting on, not quite done yet
235 | if (splitOnChars.length >= 0 && splitChar !== "") {
236 | applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk);
237 | chunks = null;
238 | }
239 | else {
240 | // Finished!
241 | return element.innerHTML;
242 | }
243 | }
244 | }
245 | else {
246 | // No valid chunks produced
247 | // No valid chunks even when splitting by letter, time to move
248 | // on to the next node
249 | if (splitChar === "") {
250 | applyEllipsis(target, "");
251 | target = getLastChild(element);
252 | reset();
253 | }
254 | }
255 | return truncate(target, maxHeight);
256 | }
257 | // CONSTRUCTOR ________________________________________________________________
258 | if (clampValue === "auto") {
259 | clampValue = getMaxLines().toString();
260 | }
261 | else if (isCSSValue) {
262 | clampValue = getMaxLines(parseInt(clampValue, 10)).toString();
263 | }
264 | var clampedText;
265 | var height = getMaxHeight(Number(clampValue));
266 | if (height < getElemHeight(element)) {
267 | clampedText = truncate(getLastChild(element), height);
268 | }
269 | return new ClampResponse(originalText, clampedText);
270 | }
271 |
272 | exports.ClampOptions = ClampOptions;
273 | exports.ClampResponse = ClampResponse;
274 | exports.clamp = clamp;
275 |
276 | Object.defineProperty(exports, '__esModule', { value: true });
277 |
278 | })));
279 |
280 | });
281 |
282 | var clampy_umd$1 = unwrapExports(clampy_umd);
283 |
284 |
285 | var clampy_ = Object.freeze({
286 | default: clampy_umd$1,
287 | __moduleExports: clampy_umd
288 | });
289 |
290 | // import * as elementResizeDetectorMaker_ from 'element-resize-detector';
291 |
292 | // https://github.com/rollup/rollup/issues/670#issuecomment-284621537
293 | var clampy = clampy_umd$1 || clampy_;
294 | // const elementResizeDetectorMaker = (elementResizeDetectorMaker_).default || elementResizeDetectorMaker_;
295 |
296 | // const resizeDetector = elementResizeDetectorMaker({ strategy: 'scroll' });
297 | var clampValue;
298 |
299 | var _extends = Object.assign || function (target) {
300 | for (var i = 1; i < arguments.length; i++) {
301 | var source = arguments[i];
302 |
303 | for (var key in source) {
304 | if (Object.prototype.hasOwnProperty.call(source, key)) {
305 | target[key] = source[key];
306 | }
307 | }
308 | }
309 |
310 | return target;
311 | };
312 |
313 | var defaults = {
314 | clamp: 'auto',
315 | truncationChar: '…',
316 | splitOnChars: ['.', '-', '–', '—', ' '],
317 | useNativeClamp: false
318 | };
319 |
320 | function setDefaults(options) {
321 | defaults = _extends({}, defaults, options);
322 | }
323 |
324 | function setup(el, clampValue) {
325 | tearDown(el);
326 |
327 | var resizeListener = function resizeListener() {
328 | clampElement(el, clampValue);
329 | };
330 |
331 | el.__VueClampy = {
332 | clampValue: clampValue,
333 | resizeListener: resizeListener
334 | };
335 |
336 | // Re-clamp on element resize
337 | // resizeDetector.listenTo(el, () => {
338 | // clampElement(el, clampValue);
339 | // });
340 |
341 | // Also re-clamp on window resize
342 | window.addEventListener('resize', resizeListener);
343 |
344 | clampElement(el, clampValue);
345 | }
346 |
347 | function tearDown(el) {
348 | if (!el || !el.__VueClampy) return;
349 | // Remove all listeners
350 | // resizeDetector.removeAllListeners(el);
351 | window.removeEventListener('resize', el.__VueClampy.resizeListener);
352 | }
353 |
354 | function setInitialContent(el) {
355 | if (el.clampInitialContent === undefined) {
356 | el.clampInitialContent = el.innerHTML.trim();
357 | }
358 | }
359 |
360 | function clampElement(el, clamp) {
361 | // We use element-resize-detector to trigger the ellipsis.
362 | // Element-resize-detector adds an inner div to monitor
363 | // it's scroll events.
364 | // The process of truncating the text for ellipsis removes this div, so we need to remove and readd it
365 | var scrollNode = el.querySelector('.erd_scroll_detection_container');
366 | if (scrollNode) {
367 | el.removeChild(scrollNode);
368 | }
369 |
370 | setInitialContent(el);
371 |
372 | if (el.clampInitialContent !== undefined) {
373 | el.innerHTML = el.clampInitialContent;
374 | }
375 |
376 | defaults = _extends({}, defaults, { clamp: clamp ? clamp : 'auto' });
377 |
378 | // Set the opacity to 0 to avoid content to flick when clamping.
379 | el.style.opacity = '0';
380 | var result = clampy.clamp(el, defaults);
381 |
382 | // Set the opacity back to 1 now that the content is clamped.
383 | el.style.opacity = '1';
384 |
385 | if (scrollNode) {
386 | el.appendChild(scrollNode);
387 | }
388 | }
389 |
390 | var VueClampy$1 = {
391 | inserted: function inserted(el, binding, vnode) {
392 | clampValue = binding.value;
393 | setup(el, clampValue);
394 | },
395 | update: function update(el, binding, vnode) {
396 | clampValue = binding.value;
397 | setup(el, clampValue);
398 | },
399 | unbind: function unbind(el, binding, vnode) {
400 | tearDown(el);
401 | delete el.__VueClampy;
402 | }
403 | };
404 |
405 | var install = function install(Vue, options) {
406 | if (options) setDefaults(options);
407 | Vue.directive('clampy', VueClampy$1);
408 | Vue.prototype.$clampy = VueClampy$1.clampy;
409 | };
410 |
411 | if (typeof window !== 'undefined' && window.Vue) {
412 | window.VueClampy = VueClampy$1;
413 | window.VueClampy.setDefaults = setDefaults;
414 | Vue.use(install);
415 | }
416 |
417 | VueClampy$1.install = install;
418 |
419 | return VueClampy$1;
420 |
421 | })));
422 |
--------------------------------------------------------------------------------