Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
149 lines
3.9 KiB
JavaScript
Executable file
149 lines
3.9 KiB
JavaScript
Executable file
/* -*- Mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
|
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
|
|
|
/* exported getTruncated */
|
|
|
|
'use strict';
|
|
|
|
function getTruncated(oldName, options) {
|
|
|
|
// options
|
|
var maxLine = options.maxLine || 2;
|
|
var node = options.node;
|
|
var ellipsisIndex = options.ellipsisIndex || 3;
|
|
var ellipsisCharacter = options.ellipsisCharacter || '...';
|
|
|
|
if (node === null) {
|
|
return oldName;
|
|
}
|
|
|
|
// used variables and functions
|
|
function hitsNewline(oldHeight, newHeight) {
|
|
return oldHeight !== newHeight;
|
|
}
|
|
|
|
var newName = '';
|
|
var oldHeight;
|
|
var newHeight;
|
|
var baseHeight;
|
|
var currentLine;
|
|
var ellipsisAt;
|
|
var hasNewEllipsisPoint = true;
|
|
var nameBeforeEllipsis = [];
|
|
var nameBeforeEllipsisString;
|
|
var nameAfterEllipsis = oldName.slice(-ellipsisIndex);
|
|
var realVisibility = node.style.visibility;
|
|
var realWordBreak = node.style.wordBreak;
|
|
|
|
/*
|
|
* Hide UI, because we are manipulating DOM
|
|
*/
|
|
node.style.visibility = 'hidden';
|
|
|
|
/*
|
|
* Force breaking on boundaries
|
|
*/
|
|
node.style.wordBreak = 'break-all';
|
|
|
|
/*
|
|
* Get the base height to count the currentLine at first
|
|
*/
|
|
node.textContent = '.';
|
|
baseHeight = node.clientHeight;
|
|
node.textContent = '';
|
|
|
|
var needEllipsis = oldName.split('').some(function(character, index) {
|
|
|
|
nameBeforeEllipsis.push(character);
|
|
nameBeforeEllipsisString = nameBeforeEllipsis.join('');
|
|
|
|
oldHeight = node.clientHeight;
|
|
node.textContent = nameBeforeEllipsisString +
|
|
ellipsisCharacter + nameAfterEllipsis;
|
|
newHeight = node.clientHeight;
|
|
|
|
/*
|
|
* When index is 0, we have to update currentLine according to
|
|
* the first assignment (it is possible that at first the currentLine
|
|
* is not 0 if the width of node is too small)
|
|
*/
|
|
if (index === 0) {
|
|
currentLine = Math.floor(newHeight / baseHeight);
|
|
}
|
|
|
|
if (hitsNewline(oldHeight, newHeight) && index !== 0) {
|
|
|
|
/*
|
|
* The reason why we have to check twice is because there is a
|
|
* situation that truncated string is overflowed but there is
|
|
* still room for original string.
|
|
*
|
|
* In this way, we have to memorize the ellipsis index and
|
|
* slice `nameBeforeEllipsis` to the index in the end.
|
|
*/
|
|
var testHeight;
|
|
node.textContent = nameBeforeEllipsisString;
|
|
testHeight = node.clientHeight;
|
|
|
|
if (hitsNewline(oldHeight, testHeight)) {
|
|
|
|
/*
|
|
* We have to make it true again to keep the ellipsisAt
|
|
* up to date.
|
|
*/
|
|
hasNewEllipsisPoint = true;
|
|
currentLine += 1;
|
|
} else {
|
|
/*
|
|
* This is the situation that we still have room, so we have
|
|
* to keep the ellipsisAt value for later use.
|
|
*/
|
|
if (hasNewEllipsisPoint) {
|
|
ellipsisAt = index;
|
|
hasNewEllipsisPoint = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (currentLine > maxLine) {
|
|
if (index === 0) {
|
|
|
|
/*
|
|
* It means that at first, the whole string is already in
|
|
* an overflowed situation, you have to avoid this situation.
|
|
* And we will bypass oldName back to you.
|
|
*
|
|
* There are some options for you :
|
|
*
|
|
* 1. Check options.ellipsisCharacter
|
|
* 2. Check options.maxLine
|
|
* 3. Check node's width (maybe too narrow)
|
|
*/
|
|
console.log(
|
|
'Your string is in a overflowed situation, ' +
|
|
'please check your options');
|
|
}
|
|
|
|
/*
|
|
* Remove the last character, because it causes the overflow
|
|
*/
|
|
nameBeforeEllipsis.pop();
|
|
node.textContent = '';
|
|
return true;
|
|
}
|
|
});
|
|
|
|
// restore UI
|
|
node.style.visibility = realVisibility;
|
|
node.style.wordBreak = realWordBreak;
|
|
|
|
if (!needEllipsis) {
|
|
newName = oldName;
|
|
} else {
|
|
newName += nameBeforeEllipsis.join('').slice(0, ellipsisAt);
|
|
newName += ellipsisCharacter;
|
|
newName += nameAfterEllipsis;
|
|
}
|
|
|
|
return newName;
|
|
}
|