VulpesOS/gaia/apps/bluetooth/js/utils.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

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;
}