From 23a5372735c85b19a0bc37fca7254074e410a42b Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Wed, 22 Feb 2017 14:34:19 -0800 Subject: [PATCH 01/12] Move initials creation logic to utility This will enable easy unit testing, re-use, etc. going forward. --- .../src/components/Persona/Persona.tsx | 53 +------------------ packages/utilities/src/index.ts | 1 + packages/utilities/src/initials.ts | 49 +++++++++++++++++ 3 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 packages/utilities/src/initials.ts diff --git a/packages/office-ui-fabric-react/src/components/Persona/Persona.tsx b/packages/office-ui-fabric-react/src/components/Persona/Persona.tsx index 11a75f4504ad6..c0e19b357c36a 100644 --- a/packages/office-ui-fabric-react/src/components/Persona/Persona.tsx +++ b/packages/office-ui-fabric-react/src/components/Persona/Persona.tsx @@ -3,6 +3,7 @@ import { autobind, css, divProperties, + getInitials, getNativeProps, getRTL } from '../../Utilities'; @@ -20,23 +21,6 @@ import { } from './PersonaConsts'; import './Persona.scss'; -/** Regex to detect words within paraenthesis in a string where gi implies global and case-insensitive. */ -const CHARS_WITHIN_PARENTHESIS_REGEX: RegExp = new RegExp('\\(([^)]*)\\)', 'gi'); - -/** - * Matches any non-word characters with respect to the Unicode codepoints; generated by - * https://mothereff.in/regexpu for regex /\W /u where u stands for Unicode support (ES6 feature). - * More info here: http://stackoverflow.com/questions/280712/javascript-unicode-regexes. - * gi implies global and case-insensitive. - */ -const UNICODE_ALPHANUMERIC_CHARS_REGEX = - new RegExp( - '(?:[\0-/:-@\[-\^`\{-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]) ', - 'gi'); - -/** Regex to detect multiple spaces in a string where gi implies global and case-insensitive. */ -const MULTIPLE_WHITESPACES_REGEX_TOKEN: RegExp = new RegExp('\\s+', 'gi'); - // The RGB color swatches const COLOR_SWATCHES_LOOKUP: PersonaInitialsColor[] = [ PersonaInitialsColor.lightGreen, @@ -95,7 +79,7 @@ export class Persona extends React.Component { let isRTL = getRTL(); - imageInitials = imageInitials || this._getInitials(primaryText, isRTL); + imageInitials = imageInitials || getInitials(primaryText, isRTL); initialsColor = initialsColor !== undefined && initialsColor !== null ? initialsColor : this._getColorFromName(primaryText); let presenceElement = null; @@ -158,39 +142,6 @@ export class Persona extends React.Component { ); } - /** Get (up to 2 characters) initials based on display name of the persona. */ - private _getInitials(displayName: string, isRtl: boolean): string { - let initials = ''; - - if (displayName != null) { - // Do not consider the suffixes within parenthesis while computing the initials. - let personaName: string = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); - personaName = personaName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); - personaName = personaName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); - - // Trim leading and trailing spaces if any. - personaName = personaName.trim(); - - const splits: string[] = personaName.split(' '); - - if (splits.length === 2) { - initials += splits[0].charAt(0).toUpperCase(); - initials += splits[1].charAt(0).toUpperCase(); - } else if (splits.length === 3) { - initials += splits[0].charAt(0).toUpperCase(); - initials += splits[2].charAt(0).toUpperCase(); - } else if (splits.length !== 0) { - initials += splits[0].charAt(0).toUpperCase(); - } - } - - if (isRtl && initials.length > 1) { - return initials.charAt(1) + initials.charAt(0); - } - - return initials; - } - private _getColorFromName(displayName: string): PersonaInitialsColor { let color = PersonaInitialsColor.blue; if (!displayName) { diff --git a/packages/utilities/src/index.ts b/packages/utilities/src/index.ts index 17aa92ebded2e..57d115fe9cbc0 100644 --- a/packages/utilities/src/index.ts +++ b/packages/utilities/src/index.ts @@ -15,6 +15,7 @@ export * from './css'; export * from './dom'; export * from './focus'; export * from './hoist'; +export * from './initials'; export * from './math'; export * from './object'; export * from './properties'; diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts new file mode 100644 index 0000000000000..88010073be5b5 --- /dev/null +++ b/packages/utilities/src/initials.ts @@ -0,0 +1,49 @@ +/** Regex to detect words within paraenthesis in a string where gi implies global and case-insensitive. */ +const CHARS_WITHIN_PARENTHESIS_REGEX: RegExp = new RegExp('\\(([^)]*)\\)', 'gi'); + +/** + * Matches any non-word characters with respect to the Unicode codepoints; generated by + * https://mothereff.in/regexpu for regex /\W /u where u stands for Unicode support (ES6 feature). + * More info here: http://stackoverflow.com/questions/280712/javascript-unicode-regexes. + * gi implies global and case-insensitive. + */ +const UNICODE_ALPHANUMERIC_CHARS_REGEX = + new RegExp( + '(?:[\0-/:-@\[-\^`\{-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]) ', + 'gi'); + +/** Regex to detect multiple spaces in a string where gi implies global and case-insensitive. */ +const MULTIPLE_WHITESPACES_REGEX_TOKEN: RegExp = new RegExp('\\s+', 'gi'); + +/** Get (up to 2 characters) initials based on display name of the persona. */ +export function getInitials(displayName: string, isRtl: boolean): string { + let initials = ''; + + if (displayName != null) { + // Do not consider the suffixes within parenthesis while computing the initials. + let personaName: string = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); + personaName = personaName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); + personaName = personaName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); + + // Trim leading and trailing spaces if any. + personaName = personaName.trim(); + + const splits: string[] = personaName.split(' '); + + if (splits.length === 2) { + initials += splits[0].charAt(0).toUpperCase(); + initials += splits[1].charAt(0).toUpperCase(); + } else if (splits.length === 3) { + initials += splits[0].charAt(0).toUpperCase(); + initials += splits[2].charAt(0).toUpperCase(); + } else if (splits.length !== 0) { + initials += splits[0].charAt(0).toUpperCase(); + } + } + + if (isRtl && initials.length > 1) { + return initials.charAt(1) + initials.charAt(0); + } + + return initials; +} From 5dd5ad2494de12bd7075f4e2ffdcdccac80bd894 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Wed, 22 Feb 2017 14:45:26 -0800 Subject: [PATCH 02/12] Move initials-specific tests to initials utility --- .../src/components/Persona/Persona.test.tsx | 15 ---------- packages/utilities/src/initials.test.ts | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 packages/utilities/src/initials.test.ts diff --git a/packages/office-ui-fabric-react/src/components/Persona/Persona.test.tsx b/packages/office-ui-fabric-react/src/components/Persona/Persona.test.tsx index 2447c34207c96..f1aa2646d2410 100644 --- a/packages/office-ui-fabric-react/src/components/Persona/Persona.test.tsx +++ b/packages/office-ui-fabric-react/src/components/Persona/Persona.test.tsx @@ -35,21 +35,6 @@ describe('Persona', () => { let result = wrapper.find('.ms-Persona-initials'); expect(result).to.have.length(1); expect(result.text()).to.equal('KL'); - - wrapper = shallow(); - result = wrapper.find('.ms-Persona-initials'); - expect(result).to.have.length(1); - expect(result.text()).to.equal('DZ'); - - wrapper = shallow(); - result = wrapper.find('.ms-Persona-initials'); - expect(result).to.have.length(1); - expect(result.text()).to.equal('44'); - - wrapper = shallow(); - result = wrapper.find('.ms-Persona-initials'); - expect(result).to.have.length(1); - expect(result.text()).to.equal('D'); }); it('calculates an expected initials in RTL if one was not specified', () => { diff --git a/packages/utilities/src/initials.test.ts b/packages/utilities/src/initials.test.ts new file mode 100644 index 0000000000000..f365cbdda1819 --- /dev/null +++ b/packages/utilities/src/initials.test.ts @@ -0,0 +1,30 @@ +import { getInitials } from './initials'; + +let { expect } = chai; + +describe('getInitials', () => { + it('calculates an expected initials in LTR', () => { + let result = getInitials('Kat Larrson', false); + expect(result).to.equal('KL'); + }); + + it('calculates an expected initials in LTR with a hypen', () => { + let result = getInitials('David Zearing-Goff', false); + expect(result).to.equal('DZ'); + }); + + it('calculates an expected initials in LTR with numbers', () => { + let result = getInitials('4lex 4loo', false); + expect(result).to.equal('44'); + }); + + it('calculates an expected initials in LTR with parentheses', () => { + let result = getInitials('David (The man) Goff', false); + expect(result).to.equal('D'); + }); + + it('calculates an expected initials in RTL if one was not specified', () => { + let result = getInitials('Kat Larrson', true); + expect(result).to.equal('LK'); + }); +}); From c6ae6aca643fdc496cd5fb321641c3504b97e167 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 11:18:24 -0800 Subject: [PATCH 03/12] Reduce function nesting: early out for bad inputs --- packages/utilities/src/initials.test.ts | 8 +++++ packages/utilities/src/initials.ts | 42 +++++++++++++------------ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/utilities/src/initials.test.ts b/packages/utilities/src/initials.test.ts index f365cbdda1819..916142cbfc54d 100644 --- a/packages/utilities/src/initials.test.ts +++ b/packages/utilities/src/initials.test.ts @@ -3,6 +3,14 @@ import { getInitials } from './initials'; let { expect } = chai; describe('getInitials', () => { + it('handles null inputs', () => { + let result = getInitials(null, false); + expect(result).to.equal(''); + + result = getInitials(undefined, false); + expect(result).to.equal(''); + }); + it('calculates an expected initials in LTR', () => { let result = getInitials('Kat Larrson', false); expect(result).to.equal('KL'); diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index 88010073be5b5..17235a0862682 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -17,28 +17,30 @@ const MULTIPLE_WHITESPACES_REGEX_TOKEN: RegExp = new RegExp('\\s+', 'gi'); /** Get (up to 2 characters) initials based on display name of the persona. */ export function getInitials(displayName: string, isRtl: boolean): string { + if (displayName == null) { + return ''; + } + let initials = ''; - if (displayName != null) { - // Do not consider the suffixes within parenthesis while computing the initials. - let personaName: string = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); - personaName = personaName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); - personaName = personaName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); - - // Trim leading and trailing spaces if any. - personaName = personaName.trim(); - - const splits: string[] = personaName.split(' '); - - if (splits.length === 2) { - initials += splits[0].charAt(0).toUpperCase(); - initials += splits[1].charAt(0).toUpperCase(); - } else if (splits.length === 3) { - initials += splits[0].charAt(0).toUpperCase(); - initials += splits[2].charAt(0).toUpperCase(); - } else if (splits.length !== 0) { - initials += splits[0].charAt(0).toUpperCase(); - } + // Do not consider the suffixes within parenthesis while computing the initials. + let personaName: string = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); + personaName = personaName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); + personaName = personaName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); + + // Trim leading and trailing spaces if any. + personaName = personaName.trim(); + + const splits: string[] = personaName.split(' '); + + if (splits.length === 2) { + initials += splits[0].charAt(0).toUpperCase(); + initials += splits[1].charAt(0).toUpperCase(); + } else if (splits.length === 3) { + initials += splits[0].charAt(0).toUpperCase(); + initials += splits[2].charAt(0).toUpperCase(); + } else if (splits.length !== 0) { + initials += splits[0].charAt(0).toUpperCase(); } if (isRtl && initials.length > 1) { From 6b1ea71426f5e3bfb838a2424952558c457a521e Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 11:23:58 -0800 Subject: [PATCH 04/12] Improve world-readiness of initials algorithm Add some special-case handling for: 1) Chinese and Korean names for which the rules for latin-alphabet names produce non-sensical results. 2) Arabic names for which the latin-rules produce potentially offensive results due to ligature contraction. Note that both of these world-readiness fixes are guaranteed to keep the existing contract that the initials function returns at most 2 characters. --- packages/utilities/src/initials.test.ts | 24 +++++++++++++ packages/utilities/src/initials.ts | 47 ++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/packages/utilities/src/initials.test.ts b/packages/utilities/src/initials.test.ts index 916142cbfc54d..9aa24e06a1e75 100644 --- a/packages/utilities/src/initials.test.ts +++ b/packages/utilities/src/initials.test.ts @@ -35,4 +35,28 @@ describe('getInitials', () => { let result = getInitials('Kat Larrson', true); expect(result).to.equal('LK'); }); + + it('calculates an expected initials for Arabic names', () => { + let result = getInitials('خسرو رحیمی', true); + expect(result).to.equal('ی'); + }); + + it('calculates an expected initials for Chinese names', () => { + let result = getInitials('桂英', false); + expect(result).to.equal('英'); + + result = getInitials('佳', false); + expect(result).to.equal('佳'); + }); + + it('calculates an expected initials for Korean names', () => { + let result = getInitials('강현', false); + expect(result).to.equal('현'); + + result = getInitials('최종래', false); + expect(result).to.equal('종래'); + + result = getInitials('남궁 성종', false); + expect(result).to.equal('성종'); + }); }); diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index 17235a0862682..dc0e22bea1964 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -15,12 +15,34 @@ const UNICODE_ALPHANUMERIC_CHARS_REGEX = /** Regex to detect multiple spaces in a string where gi implies global and case-insensitive. */ const MULTIPLE_WHITESPACES_REGEX_TOKEN: RegExp = new RegExp('\\s+', 'gi'); -/** Get (up to 2 characters) initials based on display name of the persona. */ -export function getInitials(displayName: string, isRtl: boolean): string { - if (displayName == null) { - return ''; +/** Regex to detect Arabic text. */ +const ARABIC_LANGUAGE_REGEX = new RegExp('[\u0621-\u064A\u0660-\u0669]'); + +/** Regex to detect Korean text. */ +const KOREAN_LANGUAGE_REGEX = new RegExp('[\u1100-\u11FF|\u3130-\u318F|\uA960-\uA97F|\uAC00-\uD7AF|\uD7B0-\uD7FF]'); + +/** Regex to detect Chinese text. */ +const CHINESE_LANGUAGE_REGEX = new RegExp('[\u4E00-\u9FCC\u3400-\u4DB5\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]'); + +function getInitialsArabic(displayName: string, isRtl: boolean): string { + let name = displayName.replace(/\s/, ''); + + return isRtl ? name[name.length - 1] : name[0]; +} + +function getInitialsAsian(displayName: string): string { + let name = displayName.replace(/\s/, ''); + + // for short names, only display a single character of the family name + if (name.length <= 2) { + return name[name.length - 1]; } + // for long names, display the two most significant characters of the family name + return name.substr(name.length - 2, name.length); +} + +function getInitialsLatin(displayName: string, isRtl: boolean): string { let initials = ''; // Do not consider the suffixes within parenthesis while computing the initials. @@ -49,3 +71,20 @@ export function getInitials(displayName: string, isRtl: boolean): string { return initials; } + +/** Get (up to 2 characters) initials based on display name of the persona. */ +export function getInitials(displayName: string, isRtl: boolean): string { + if (displayName == null) { + return ''; + } + + if (ARABIC_LANGUAGE_REGEX.test(displayName)) { + return getInitialsArabic(displayName, isRtl); + } + + if (KOREAN_LANGUAGE_REGEX.test(displayName) || CHINESE_LANGUAGE_REGEX.test(displayName)) { + return getInitialsAsian(displayName); + } + + return getInitialsLatin(displayName, isRtl); +} From e2735b310006a29d028fa823492a143f6981fe90 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 13:08:38 -0800 Subject: [PATCH 05/12] Split out method for name cleanup --- packages/utilities/src/initials.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index dc0e22bea1964..75e2b87339cf5 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -45,15 +45,7 @@ function getInitialsAsian(displayName: string): string { function getInitialsLatin(displayName: string, isRtl: boolean): string { let initials = ''; - // Do not consider the suffixes within parenthesis while computing the initials. - let personaName: string = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); - personaName = personaName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); - personaName = personaName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); - - // Trim leading and trailing spaces if any. - personaName = personaName.trim(); - - const splits: string[] = personaName.split(' '); + const splits: string[] = displayName.split(' '); if (splits.length === 2) { initials += splits[0].charAt(0).toUpperCase(); @@ -72,12 +64,28 @@ function getInitialsLatin(displayName: string, isRtl: boolean): string { return initials; } +function cleanupDisplayName(displayName: string): string { + // Do not consider the suffixes within parenthesis while computing the initials. + displayName = displayName.replace(CHARS_WITHIN_PARENTHESIS_REGEX, ''); + + // Ignore non-word characters + displayName = displayName.replace(UNICODE_ALPHANUMERIC_CHARS_REGEX, ''); + + // Make whitespace consistent + displayName = displayName.replace(MULTIPLE_WHITESPACES_REGEX_TOKEN, ' '); + displayName = displayName.trim(); + + return displayName; +} + /** Get (up to 2 characters) initials based on display name of the persona. */ export function getInitials(displayName: string, isRtl: boolean): string { if (displayName == null) { return ''; } + displayName = cleanupDisplayName(displayName); + if (ARABIC_LANGUAGE_REGEX.test(displayName)) { return getInitialsArabic(displayName, isRtl); } From e1ecb24f77a8d1d0856f8d7755cf7e703527620d Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 13:09:35 -0800 Subject: [PATCH 06/12] Use const instead of let where possible --- packages/utilities/src/initials.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index 75e2b87339cf5..8a642ab2b26ce 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -25,13 +25,13 @@ const KOREAN_LANGUAGE_REGEX = new RegExp('[\u1100-\u11FF|\u3130-\u318F|\uA960-\u const CHINESE_LANGUAGE_REGEX = new RegExp('[\u4E00-\u9FCC\u3400-\u4DB5\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]'); function getInitialsArabic(displayName: string, isRtl: boolean): string { - let name = displayName.replace(/\s/, ''); + const name = displayName.replace(/\s/, ''); return isRtl ? name[name.length - 1] : name[0]; } function getInitialsAsian(displayName: string): string { - let name = displayName.replace(/\s/, ''); + const name = displayName.replace(/\s/, ''); // for short names, only display a single character of the family name if (name.length <= 2) { From ecaf872d4097eec6f1e963fcce51d0c38ea86019 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 13:12:53 -0800 Subject: [PATCH 07/12] Capitalize comments --- packages/utilities/src/initials.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index 8a642ab2b26ce..d1c5e466638ce 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -33,12 +33,12 @@ function getInitialsArabic(displayName: string, isRtl: boolean): string { function getInitialsAsian(displayName: string): string { const name = displayName.replace(/\s/, ''); - // for short names, only display a single character of the family name + // For short names, only display a single character of the family name if (name.length <= 2) { return name[name.length - 1]; } - // for long names, display the two most significant characters of the family name + // For long names, display the two most significant characters of the family name return name.substr(name.length - 2, name.length); } From 09a7bdd899bc31f540e1dacbece53974eb592906 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 13:14:49 -0800 Subject: [PATCH 08/12] Make Asian initials function RTL-aware --- packages/utilities/src/initials.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utilities/src/initials.ts b/packages/utilities/src/initials.ts index d1c5e466638ce..ed35b000a9de2 100644 --- a/packages/utilities/src/initials.ts +++ b/packages/utilities/src/initials.ts @@ -30,16 +30,16 @@ function getInitialsArabic(displayName: string, isRtl: boolean): string { return isRtl ? name[name.length - 1] : name[0]; } -function getInitialsAsian(displayName: string): string { +function getInitialsAsian(displayName: string, isRtl: boolean): string { const name = displayName.replace(/\s/, ''); // For short names, only display a single character of the family name if (name.length <= 2) { - return name[name.length - 1]; + return isRtl ? name[0] : name[name.length - 1]; } // For long names, display the two most significant characters of the family name - return name.substr(name.length - 2, name.length); + return isRtl ? name.substr(0, 2) : name.substr(name.length - 2, name.length); } function getInitialsLatin(displayName: string, isRtl: boolean): string { @@ -91,7 +91,7 @@ export function getInitials(displayName: string, isRtl: boolean): string { } if (KOREAN_LANGUAGE_REGEX.test(displayName) || CHINESE_LANGUAGE_REGEX.test(displayName)) { - return getInitialsAsian(displayName); + return getInitialsAsian(displayName, isRtl); } return getInitialsLatin(displayName, isRtl); From f414fd5d4b2a1d7d9f849ff5fe104ad2d74e2d44 Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 15:38:00 -0800 Subject: [PATCH 09/12] Add test for long Chinese names We need to ensure that even for names with three or more characters, the generated initials don't contain more than two characters. --- packages/utilities/src/initials.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/utilities/src/initials.test.ts b/packages/utilities/src/initials.test.ts index 9aa24e06a1e75..a5661ff8d8aab 100644 --- a/packages/utilities/src/initials.test.ts +++ b/packages/utilities/src/initials.test.ts @@ -47,6 +47,9 @@ describe('getInitials', () => { result = getInitials('佳', false); expect(result).to.equal('佳'); + + result = getInitials('宋智洋', false); + expect(result).to.equal('智洋'); }); it('calculates an expected initials for Korean names', () => { From 8d29d37c1ac83378d932a0dbe597d07c542e09fd Mon Sep 17 00:00:00 2001 From: Clemens Wolff Date: Fri, 24 Feb 2017 15:52:24 -0800 Subject: [PATCH 10/12] Add personas with non-Latin names to the examples --- .../examples/Persona.Initials.Example.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/fabric-examples/src/pages/PersonaPage/examples/Persona.Initials.Example.tsx b/apps/fabric-examples/src/pages/PersonaPage/examples/Persona.Initials.Example.tsx index 21b87a2ddb99a..4fd7292f6668f 100644 --- a/apps/fabric-examples/src/pages/PersonaPage/examples/Persona.Initials.Example.tsx +++ b/apps/fabric-examples/src/pages/PersonaPage/examples/Persona.Initials.Example.tsx @@ -28,6 +28,18 @@ export class PersonaInitialsExample extends React.Component { { ...examplePersona } primaryText='Annie Lindqvist' /> + + + Date: Fri, 24 Feb 2017 16:07:25 -0800 Subject: [PATCH 11/12] Add changefile --- ...adiness-of-initials-algorithm_2017-02-24-16-06.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json diff --git a/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json b/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json new file mode 100644 index 0000000000000..04007f6e0fab4 --- /dev/null +++ b/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Improve abbreviation of non-Latin names in Persona component", + "type": "minor" + } + ], + "email": "clewolff@microsoft.com" +} \ No newline at end of file From cdfdc9bcbbf3154755bbbf1bd75372efb97827a7 Mon Sep 17 00:00:00 2001 From: Cliff Koh Date: Fri, 24 Feb 2017 16:34:24 -0800 Subject: [PATCH 12/12] Update improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json --- ...ld-readiness-of-initials-algorithm_2017-02-24-16-06.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json b/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json index 04007f6e0fab4..b27bfbde20ff1 100644 --- a/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json +++ b/common/changes/improve-world-readiness-of-initials-algorithm_2017-02-24-16-06.json @@ -2,9 +2,9 @@ "changes": [ { "packageName": "office-ui-fabric-react", - "comment": "Improve abbreviation of non-Latin names in Persona component", - "type": "minor" + "comment": "Persona: Improve default manner of abbreviating non-Latin names.", + "type": "patch" } ], "email": "clewolff@microsoft.com" -} \ No newline at end of file +}