getInitials: handle more cases
See [#5029]][0]. [0]: https://github.com/signalapp/Signal-Desktop/pull/5029
This commit is contained in:
parent
7438590bc0
commit
d20cc59a26
2 changed files with 81 additions and 12 deletions
62
ts/test-both/util/getInitials_test.ts
Normal file
62
ts/test-both/util/getInitials_test.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { getInitials } from '../../util/getInitials';
|
||||
|
||||
describe('getInitials', () => {
|
||||
it('returns undefined when passed undefined', () => {
|
||||
assert.isUndefined(getInitials(undefined));
|
||||
});
|
||||
|
||||
it('returns undefined when passed an empty string', () => {
|
||||
assert.isUndefined(getInitials(''));
|
||||
});
|
||||
|
||||
it('returns undefined when passed a string with no letters', () => {
|
||||
assert.isUndefined(getInitials('123 !@#$%'));
|
||||
});
|
||||
|
||||
it('returns the first letter of a name that is one ASCII word', () => {
|
||||
assert.strictEqual(getInitials('Foo'), 'F');
|
||||
assert.strictEqual(getInitials('Bo'), 'B');
|
||||
});
|
||||
|
||||
[
|
||||
'Foo Bar',
|
||||
'foo bar',
|
||||
'F Bar',
|
||||
'Foo B',
|
||||
'FB',
|
||||
'F.B.',
|
||||
'0Foo 1Bar',
|
||||
"Foo B'Ar",
|
||||
'Foo Q Bar',
|
||||
'Foo Q. Bar',
|
||||
'Foo Qux Bar',
|
||||
'Foo "Qux" Bar',
|
||||
'Foo-Qux Bar',
|
||||
'Foo Bar-Qux',
|
||||
"Foo b'Arr",
|
||||
].forEach(name => {
|
||||
it(`returns 'FB' for '${name}'`, () => {
|
||||
assert.strictEqual(getInitials(name), 'FB');
|
||||
});
|
||||
});
|
||||
|
||||
it('returns initials for languages with non-Latin alphabets', () => {
|
||||
assert.strictEqual(getInitials('Иван Иванов'), 'ИИ');
|
||||
assert.strictEqual(getInitials('山田 太郎'), '山太');
|
||||
assert.strictEqual(getInitials('王五'), '王五');
|
||||
});
|
||||
|
||||
it('returns initials for right-to-left languages', () => {
|
||||
assert.strictEqual(getInitials('فلانة الفلانية'), 'فا');
|
||||
assert.strictEqual(getInitials('ישראלה ישראלי'), 'יי');
|
||||
});
|
||||
|
||||
it('returns initials with diacritical marks', () => {
|
||||
assert.strictEqual(getInitials('Ḟoo Ḅar'), 'ḞḄ');
|
||||
});
|
||||
});
|
|
@ -1,24 +1,31 @@
|
|||
// Copyright 2018-2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
const BAD_CHARACTERS = /[^A-Za-z\s]+/g;
|
||||
const WHITESPACE = /\s+/g;
|
||||
|
||||
function removeNonInitials(name: string) {
|
||||
return name.replace(BAD_CHARACTERS, '').replace(WHITESPACE, ' ');
|
||||
}
|
||||
|
||||
export function getInitials(name?: string): string | undefined {
|
||||
if (!name) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const cleaned = removeNonInitials(name);
|
||||
const parts = cleaned.split(' ');
|
||||
const initials = parts.map(part => part.trim()[0]);
|
||||
if (!initials.length) {
|
||||
const parsedName = name
|
||||
// remove all chars that are not letters or separators
|
||||
.replace(/[^\p{L}\p{Z}]+/gu, '')
|
||||
// replace all chars that are separators with a single ASCII space
|
||||
.replace(/\p{Z}+/gu, ' ')
|
||||
.trim();
|
||||
|
||||
if (!parsedName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return initials.slice(0, 2).join('');
|
||||
// check if chars in the parsed string are initials
|
||||
if (parsedName.length === 2 && parsedName === parsedName.toUpperCase()) {
|
||||
return parsedName;
|
||||
}
|
||||
|
||||
const parts = parsedName.toUpperCase().split(' ');
|
||||
const partsLen = parts.length;
|
||||
|
||||
return partsLen === 1
|
||||
? parts[0].charAt(0)
|
||||
: parts[0].charAt(0) + parts[partsLen - 1].charAt(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue