mirror of
https://github.com/faisalman/ua-parser-js.git
synced 2026-01-16 08:27:12 +03:00
feat(email): expand email client detection & add Outlook edition helper (#819)
* feat(email): significantly expanded email client detection to support 40+ new user agents, including Alpine, Canary Mail, FairEmail, ProtonMail Bridge, Tutanota, and The Bat! feat(helpers): added getOutlookEdition() utility to interpret raw version strings into specific Outlook editions (e.g., distinguishing Outlook 2016 MSI vs. Click-to-Run/365). chore(enums): added comprehensive BrowserName.Email enums for all newly supported clients. chore(types): added TypeScript definitions for the new getOutlookEdition helper. test(email): added comprehensive test suite covering 60+ email client user agent strings. test(helpers): added unit tests for getOutlookEdition covering Windows (MSI/C2R) and Mac variants. * chore: Some small updates for business logic around K-9, Yahoo Mail, Outlook * test: Edgecase alignment and fixes chore(deps): npm vulnerability fix in package-lock.json chore: Updated dist builds * Revert accidentally-removed additional code and comments * Correct comment syntax in ua-parser-extensions.js Fix comment formatting and clean up code. * chore: build fix
This commit is contained in:
46
src/enums/ua-parser-enums.d.ts
vendored
46
src/enums/ua-parser-enums.d.ts
vendored
@@ -613,24 +613,66 @@ export const Extension: Readonly<{
|
||||
},
|
||||
Email: {
|
||||
AIRMAIL: 'Airmail',
|
||||
ALPINE: 'Alpine',
|
||||
ANDROID_MAIL: 'Android',
|
||||
APPLE_MAIL: 'Mail',
|
||||
AQUA_MAIL: 'AquaMail',
|
||||
BALSA: 'Balsa',
|
||||
BARCA: 'Barca',
|
||||
BLUEMAIL: 'BlueMail',
|
||||
CANARY: 'Canary',
|
||||
CLAWS_MAIL: 'Claws Mail',
|
||||
DAUM_MAIL: 'DaumMail',
|
||||
EVOLUTION: 'Evolution',
|
||||
EM_CLIENT: 'eM Client',
|
||||
EUDORA: 'Eudora',
|
||||
EVOLUTION: 'Evolution',
|
||||
FAIR_EMAIL: 'FairEmail',
|
||||
FOXMAIL: 'Foxmail',
|
||||
GEARY: 'Geary',
|
||||
GNUS: 'Gnus',
|
||||
HORDE_IMP: 'Horde::IMP',
|
||||
IBM_NOTES: 'Lotus-Notes',
|
||||
INCREDIMAIL: 'IncrediMail',
|
||||
K9_MAIL: 'K-9 Mail',
|
||||
KMAIL: 'KMail',
|
||||
KMAIL2: 'kmail2',
|
||||
KONTACT: 'Kontact',
|
||||
MAILBIRD: 'Mailbird',
|
||||
MAILMATE: 'MailMate',
|
||||
MAILSPRING: 'Mailspring',
|
||||
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
|
||||
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
|
||||
MUTT: 'Mutt',
|
||||
NAVER_MAILAPP: 'NaverMailApp',
|
||||
NEWTON: 'Newton',
|
||||
NINE: 'Nine',
|
||||
NYLAS_MAIL: 'NylasMail',
|
||||
OUTLOOK_EXPRESS: 'Outlook-Express',
|
||||
PEGASUS_MAIL: 'Pegasus Mail',
|
||||
POCOMAIL: 'PocoMail',
|
||||
POLYMAIL: 'Polymail',
|
||||
POSTBOX: 'Postbox',
|
||||
PROTON_MAIL: 'ProtonMail',
|
||||
PROTON_MAIL_BRIDGE: 'ProtonMail Bridge',
|
||||
QUALA_MAIL: 'Quala',
|
||||
R2MAIL2: 'R2Mail2',
|
||||
RAINLOOP: 'RainLoop',
|
||||
ROUNDCUBE: 'Roundcube Webmail',
|
||||
SAMSUNG_EMAIL: 'SamsungEmail',
|
||||
SPARK_MAIL: 'SparkDesktop',
|
||||
SPARROW: 'Sparrow',
|
||||
SPICEBIRD: 'Spicebird',
|
||||
SQUIRRELMAIL: 'SquirrelMail',
|
||||
SYLPHEED: 'Sylpheed',
|
||||
THE_BAT: 'The Bat!',
|
||||
THUNDERBIRD: 'Thunderbird',
|
||||
YAHOO_MAIL: 'Yahoo',
|
||||
TROJITA: 'Trojita',
|
||||
TURNPIKE: 'Turnpike',
|
||||
TUTANOTA: 'tutanota-desktop',
|
||||
WANDERLUST: 'Wanderlust',
|
||||
WINDOWS_LIVE_MAIL: 'Windows-Live-Mail',
|
||||
YAHOO_MAIL: 'Yahoo Mail',
|
||||
YAHOO_MAIL_IOS: 'Yahoo Mail',
|
||||
ZIMBRA: 'Zimbra',
|
||||
ZOHO_MAIL: 'ZohoMail-Desktop'
|
||||
},
|
||||
|
||||
@@ -609,24 +609,66 @@ const Extension = Object.freeze({
|
||||
},
|
||||
Email: {
|
||||
AIRMAIL: 'Airmail',
|
||||
ALPINE: 'Alpine',
|
||||
ANDROID_MAIL: 'Android',
|
||||
APPLE_MAIL: 'Mail',
|
||||
AQUA_MAIL: 'AquaMail',
|
||||
BALSA: 'Balsa',
|
||||
BARCA: 'Barca',
|
||||
BLUEMAIL: 'BlueMail',
|
||||
CANARY: 'Canary',
|
||||
CLAWS_MAIL: 'Claws Mail',
|
||||
DAUM_MAIL: 'DaumMail',
|
||||
EVOLUTION: 'Evolution',
|
||||
EM_CLIENT: 'eM Client',
|
||||
EUDORA: 'Eudora',
|
||||
EVOLUTION: 'Evolution',
|
||||
FAIR_EMAIL: 'FairEmail',
|
||||
FOXMAIL: 'Foxmail',
|
||||
GEARY: 'Geary',
|
||||
GNUS: 'Gnus',
|
||||
HORDE_IMP: 'Horde::IMP',
|
||||
IBM_NOTES: 'Lotus-Notes',
|
||||
INCREDIMAIL: 'IncrediMail',
|
||||
K9_MAIL: 'K-9 Mail',
|
||||
KMAIL: 'KMail',
|
||||
KMAIL2: 'kmail2',
|
||||
KONTACT: 'Kontact',
|
||||
MAILBIRD: 'Mailbird',
|
||||
MAILMATE: 'MailMate',
|
||||
MAILSPRING: 'Mailspring',
|
||||
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
|
||||
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
|
||||
MUTT: 'Mutt',
|
||||
NAVER_MAILAPP: 'NaverMailApp',
|
||||
NEWTON: 'Newton',
|
||||
NINE: 'Nine',
|
||||
NYLAS_MAIL: 'NylasMail',
|
||||
OUTLOOK_EXPRESS: 'Outlook-Express',
|
||||
PEGASUS_MAIL: 'Pegasus Mail',
|
||||
POCOMAIL: 'PocoMail',
|
||||
POLYMAIL: 'Polymail',
|
||||
POSTBOX: 'Postbox',
|
||||
PROTON_MAIL: 'ProtonMail',
|
||||
PROTON_MAIL_BRIDGE: 'ProtonMail Bridge',
|
||||
QUALA_MAIL: 'Quala',
|
||||
R2MAIL2: 'R2Mail2',
|
||||
RAINLOOP: 'RainLoop',
|
||||
ROUNDCUBE: 'Roundcube Webmail',
|
||||
SAMSUNG_EMAIL: 'SamsungEmail',
|
||||
SPARK_MAIL: 'SparkDesktop',
|
||||
SPARROW: 'Sparrow',
|
||||
SPICEBIRD: 'Spicebird',
|
||||
SQUIRRELMAIL: 'SquirrelMail',
|
||||
SYLPHEED: 'Sylpheed',
|
||||
THE_BAT: 'The Bat!',
|
||||
THUNDERBIRD: 'Thunderbird',
|
||||
YAHOO_MAIL: 'Yahoo',
|
||||
TROJITA: 'Trojita',
|
||||
TURNPIKE: 'Turnpike',
|
||||
TUTANOTA: 'tutanota-desktop',
|
||||
WANDERLUST: 'Wanderlust',
|
||||
WINDOWS_LIVE_MAIL: 'Windows-Live-Mail',
|
||||
YAHOO_MAIL: 'Yahoo Mail',
|
||||
YAHOO_MAIL_IOS: 'Yahoo Mail',
|
||||
ZIMBRA: 'Zimbra',
|
||||
ZOHO_MAIL: 'ZohoMail-Desktop'
|
||||
},
|
||||
|
||||
@@ -613,24 +613,66 @@ const Extension = Object.freeze({
|
||||
},
|
||||
Email: {
|
||||
AIRMAIL: 'Airmail',
|
||||
ALPINE: 'Alpine',
|
||||
ANDROID_MAIL: 'Android',
|
||||
APPLE_MAIL: 'Mail',
|
||||
AQUA_MAIL: 'AquaMail',
|
||||
BALSA: 'Balsa',
|
||||
BARCA: 'Barca',
|
||||
BLUEMAIL: 'BlueMail',
|
||||
CANARY: 'Canary',
|
||||
CLAWS_MAIL: 'Claws Mail',
|
||||
DAUM_MAIL: 'DaumMail',
|
||||
EVOLUTION: 'Evolution',
|
||||
EM_CLIENT: 'eM Client',
|
||||
EUDORA: 'Eudora',
|
||||
EVOLUTION: 'Evolution',
|
||||
FAIR_EMAIL: 'FairEmail',
|
||||
FOXMAIL: 'Foxmail',
|
||||
GEARY: 'Geary',
|
||||
GNUS: 'Gnus',
|
||||
HORDE_IMP: 'Horde::IMP',
|
||||
IBM_NOTES: 'Lotus-Notes',
|
||||
INCREDIMAIL: 'IncrediMail',
|
||||
K9_MAIL: 'K-9 Mail',
|
||||
KMAIL: 'KMail',
|
||||
KMAIL2: 'kmail2',
|
||||
KONTACT: 'Kontact',
|
||||
MAILBIRD: 'Mailbird',
|
||||
MAILMATE: 'MailMate',
|
||||
MAILSPRING: 'Mailspring',
|
||||
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
|
||||
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
|
||||
MUTT: 'Mutt',
|
||||
NAVER_MAILAPP: 'NaverMailApp',
|
||||
NEWTON: 'Newton',
|
||||
NINE: 'Nine',
|
||||
NYLAS_MAIL: 'NylasMail',
|
||||
OUTLOOK_EXPRESS: 'Outlook-Express',
|
||||
PEGASUS_MAIL: 'Pegasus Mail',
|
||||
POCOMAIL: 'PocoMail',
|
||||
POLYMAIL: 'Polymail',
|
||||
POSTBOX: 'Postbox',
|
||||
PROTON_MAIL: 'ProtonMail',
|
||||
PROTON_MAIL_BRIDGE: 'ProtonMail Bridge',
|
||||
QUALA_MAIL: 'Quala',
|
||||
R2MAIL2: 'R2Mail2',
|
||||
RAINLOOP: 'RainLoop',
|
||||
ROUNDCUBE: 'Roundcube Webmail',
|
||||
SAMSUNG_EMAIL: 'SamsungEmail',
|
||||
SPARK_MAIL: 'SparkDesktop',
|
||||
SPARROW: 'Sparrow',
|
||||
SPICEBIRD: 'Spicebird',
|
||||
SQUIRRELMAIL: 'SquirrelMail',
|
||||
SYLPHEED: 'Sylpheed',
|
||||
THE_BAT: 'The Bat!',
|
||||
THUNDERBIRD: 'Thunderbird',
|
||||
YAHOO_MAIL: 'Yahoo',
|
||||
TROJITA: 'Trojita',
|
||||
TURNPIKE: 'Turnpike',
|
||||
TUTANOTA: 'tutanota-desktop',
|
||||
WANDERLUST: 'Wanderlust',
|
||||
WINDOWS_LIVE_MAIL: 'Windows-Live-Mail',
|
||||
YAHOO_MAIL: 'Yahoo Mail',
|
||||
YAHOO_MAIL_IOS: 'Yahoo Mail',
|
||||
ZIMBRA: 'Zimbra',
|
||||
ZOHO_MAIL: 'ZohoMail-Desktop'
|
||||
},
|
||||
|
||||
@@ -22,6 +22,19 @@ const INAPP = 'inapp';
|
||||
const MEDIAPLAYER = 'mediaplayer';
|
||||
const LIBRARY = 'library';
|
||||
|
||||
// Helper to normalize specific email client names
|
||||
const normalizeEmailName = function (str) {
|
||||
const map = {
|
||||
'YahooMobile': 'Yahoo Mail',
|
||||
'YahooMail': 'Yahoo Mail',
|
||||
'K-9': 'K-9 Mail',
|
||||
'K-9 Mail': 'K-9 Mail',
|
||||
'Zdesktop': 'Zimbra',
|
||||
'zdesktop': 'Zimbra'
|
||||
};
|
||||
return map[str] || str;
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// COMMAND LINE APPS
|
||||
/////////////////////
|
||||
@@ -229,25 +242,55 @@ const ExtraDevices = Object.freeze({
|
||||
]
|
||||
});
|
||||
|
||||
///////////////
|
||||
//////////////
|
||||
// EMAIL APPS
|
||||
//////////////
|
||||
|
||||
const Emails = Object.freeze({
|
||||
browser : [
|
||||
[
|
||||
// Evolution / Kontact/KMail[2] / [Microsoft/Mac] Outlook / Thunderbird
|
||||
// Airmail / BlueMail / DaumMail / eMClient / Foxmail / NaverMailApp / Polymail
|
||||
// ProtonMail / SparkDesktop / Sparrow / Yahoo! Mail / Zimbra / ZohoMail-Desktop
|
||||
/((?:air|blue|daum|fox|poly|proton)mail|emclient|evolution|kmail2?|kontact|(?:microsoft |mac)?outlook(?:-express)?|navermailapp|(?!chrom.+)sparrow|sparkdesktop|thunderbird|yahoo|zohomail-desktop)(?:m.+ail; |[\/ ])([\w\.]+)/i,
|
||||
// 1. Specific Android Mail Rule
|
||||
[/(android)\/([\w\.-]+email)/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]],
|
||||
|
||||
// Apple's Mail
|
||||
/(mail)\/([\w\.]+) cf/i
|
||||
], [NAME, VERSION, [TYPE, EMAIL]], [
|
||||
// 2. Standard Email Clients
|
||||
[
|
||||
new RegExp(
|
||||
'(' +
|
||||
// Clients ending in 'mail' (Case 1: Prefix + optional space + [e]mail)
|
||||
// Covers: AirMail, Claws Mail, FairEmail, SamsungEmail, Yahoo Mail, etc.
|
||||
'(?:air|aqua|blue|claws|daum|fair|fox|k-9|mac|nylas|pegasus|poco|poly|proton|samsung|squirrel|yahoo) ?e?mail(?:-desktop| app| bridge)?|' +
|
||||
// Standalone / Specific Names
|
||||
'microsoft outlook|r2mail2|spicebird|turnpike|yahoomobile|' +
|
||||
// Microsoft & Outlook Variants
|
||||
'(?:microsoft )?outlook(?:-express)?|macoutlook|windows-live-mail|' +
|
||||
// Specific Clients
|
||||
'alpine|balsa|barca|canary|emclient|eudora|evolution|geary|gnus|' +
|
||||
'horde::imp|incredimail|kmail2?|kontact|lotus-notes|' +
|
||||
'mail(?:bird|mate|spring)|mutt|navermailapp|newton|nine|postbox|' +
|
||||
'rainloop|roundcube webmail|spar(?:row|kdesktop)|sylpheed|' +
|
||||
'the bat!|thunderbird|trojita|tutanota-desktop|wanderlust|' +
|
||||
'zdesktop|zohomail-desktop' +
|
||||
')' +
|
||||
// Separator
|
||||
'(?:m.+ail; |[\\/ ])' +
|
||||
// Version (Updated to allow hyphens for Turnpike)
|
||||
'([\\w\\.-]+)',
|
||||
'i'
|
||||
)
|
||||
],
|
||||
[
|
||||
[NAME, normalizeEmailName],
|
||||
VERSION,
|
||||
[TYPE, EMAIL]
|
||||
],
|
||||
|
||||
// 3. Apple Mail Context
|
||||
[/(mail)\/([\w\.]+) cf/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]],
|
||||
|
||||
// Zimbra
|
||||
/zdesktop\/([\w\.]+)/i
|
||||
], [VERSION, [NAME, 'Zimbra'], [TYPE, EMAIL]]
|
||||
// 4. Zimbra Server
|
||||
[/(zimbra)\/([\w\.-]+)/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]]
|
||||
]
|
||||
});
|
||||
|
||||
@@ -451,4 +494,4 @@ module.exports = {
|
||||
Libraries,
|
||||
MediaPlayers,
|
||||
Vehicles
|
||||
};
|
||||
};
|
||||
|
||||
@@ -26,6 +26,19 @@ const INAPP = 'inapp';
|
||||
const MEDIAPLAYER = 'mediaplayer';
|
||||
const LIBRARY = 'library';
|
||||
|
||||
// Helper to normalize specific email client names
|
||||
const normalizeEmailName = function (str) {
|
||||
const map = {
|
||||
'YahooMobile': 'Yahoo Mail',
|
||||
'YahooMail': 'Yahoo Mail',
|
||||
'K-9': 'K-9 Mail',
|
||||
'K-9 Mail': 'K-9 Mail',
|
||||
'Zdesktop': 'Zimbra',
|
||||
'zdesktop': 'Zimbra'
|
||||
};
|
||||
return map[str] || str;
|
||||
};
|
||||
|
||||
//////////////////////
|
||||
// COMMAND LINE APPS
|
||||
/////////////////////
|
||||
@@ -233,25 +246,55 @@ const ExtraDevices = Object.freeze({
|
||||
]
|
||||
});
|
||||
|
||||
///////////////
|
||||
//////////////
|
||||
// EMAIL APPS
|
||||
//////////////
|
||||
|
||||
const Emails = Object.freeze({
|
||||
browser : [
|
||||
[
|
||||
// Evolution / Kontact/KMail[2] / [Microsoft/Mac] Outlook / Thunderbird
|
||||
// Airmail / BlueMail / DaumMail / eMClient / Foxmail / NaverMailApp / Polymail
|
||||
// ProtonMail / SparkDesktop / Sparrow / Yahoo! Mail / Zimbra / ZohoMail-Desktop
|
||||
/((?:air|blue|daum|fox|poly|proton)mail|emclient|evolution|kmail2?|kontact|(?:microsoft |mac)?outlook(?:-express)?|navermailapp|(?!chrom.+)sparrow|sparkdesktop|thunderbird|yahoo|zohomail-desktop)(?:m.+ail; |[\/ ])([\w\.]+)/i,
|
||||
// 1. Specific Android Mail Rule
|
||||
[/(android)\/([\w\.-]+email)/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]],
|
||||
|
||||
// Apple's Mail
|
||||
/(mail)\/([\w\.]+) cf/i
|
||||
], [NAME, VERSION, [TYPE, EMAIL]], [
|
||||
// 2. Standard Email Clients
|
||||
[
|
||||
new RegExp(
|
||||
'(' +
|
||||
// Clients ending in 'mail' (Case 1: Prefix + optional space + [e]mail)
|
||||
// Covers: AirMail, Claws Mail, FairEmail, SamsungEmail, Yahoo Mail, etc.
|
||||
'(?:air|aqua|blue|claws|daum|fair|fox|k-9|mac|nylas|pegasus|poco|poly|proton|samsung|squirrel|yahoo) ?e?mail(?:-desktop| app| bridge)?|' +
|
||||
// Standalone / Specific Names
|
||||
'microsoft outlook|r2mail2|spicebird|turnpike|yahoomobile|' +
|
||||
// Microsoft & Outlook Variants
|
||||
'(?:microsoft )?outlook(?:-express)?|macoutlook|windows-live-mail|' +
|
||||
// Specific Clients
|
||||
'alpine|balsa|barca|canary|emclient|eudora|evolution|geary|gnus|' +
|
||||
'horde::imp|incredimail|kmail2?|kontact|lotus-notes|' +
|
||||
'mail(?:bird|mate|spring)|mutt|navermailapp|newton|nine|postbox|' +
|
||||
'rainloop|roundcube webmail|spar(?:row|kdesktop)|sylpheed|' +
|
||||
'the bat!|thunderbird|trojita|tutanota-desktop|wanderlust|' +
|
||||
'zdesktop|zohomail-desktop' +
|
||||
')' +
|
||||
// Separator
|
||||
'(?:m.+ail; |[\\/ ])' +
|
||||
// Version (Updated to allow hyphens for Turnpike)
|
||||
'([\\w\\.-]+)',
|
||||
'i'
|
||||
)
|
||||
],
|
||||
[
|
||||
[NAME, normalizeEmailName],
|
||||
VERSION,
|
||||
[TYPE, EMAIL]
|
||||
],
|
||||
|
||||
// 3. Apple Mail Context
|
||||
[/(mail)\/([\w\.]+) cf/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]],
|
||||
|
||||
// Zimbra
|
||||
/zdesktop\/([\w\.]+)/i
|
||||
], [VERSION, [NAME, 'Zimbra'], [TYPE, EMAIL]]
|
||||
// 4. Zimbra Server
|
||||
[/(zimbra)\/([\w\.-]+)/i],
|
||||
[NAME, VERSION, [TYPE, EMAIL]]
|
||||
]
|
||||
});
|
||||
|
||||
@@ -455,4 +498,4 @@ export {
|
||||
Libraries,
|
||||
MediaPlayers,
|
||||
Vehicles
|
||||
};
|
||||
};
|
||||
|
||||
@@ -55,6 +55,50 @@ const isFromEU = _isFromEU;
|
||||
*/
|
||||
const isStandalonePWA = _isStandalonePWA;
|
||||
|
||||
/**
|
||||
* Translates a raw Outlook User-Agent name/version into a
|
||||
* Developer-friendly Edition (e.g., "Outlook 2019 (Modern Word)").
|
||||
*/
|
||||
const getOutlookEdition = (name, version) => {
|
||||
if (!name || !version) return name;
|
||||
const cleanName = name.toLowerCase().replace(/microsoft\s+/, '');
|
||||
|
||||
// 1. Handle Mac Separately (Different Rendering Engine)
|
||||
if (cleanName === 'macoutlook') {
|
||||
const major = parseInt(version.split('.')[0], 10);
|
||||
if (major >= 16) return "Outlook for Mac (Modern)";
|
||||
return "Outlook for Mac (Legacy)";
|
||||
}
|
||||
|
||||
// 2. Handle Windows Outlook
|
||||
if (cleanName === 'outlook') {
|
||||
const parts = version.split('.').map(Number);
|
||||
const major = parts[0];
|
||||
const build = parts[2] || 0; // Build number is usually the 3rd part
|
||||
|
||||
// Pre-2016 Versions (Clear Major Version mapping)
|
||||
if (major === 15) return "Outlook 2013";
|
||||
if (major === 14) return "Outlook 2010";
|
||||
if (major === 12) return "Outlook 2007";
|
||||
if (major < 12) return "Outlook (Legacy)";
|
||||
|
||||
// The Version 16.0 Confusion
|
||||
if (major === 16) {
|
||||
// Build < 10000 = MSI (Volume License 2016/2019)
|
||||
// These render poorly (No SVG, older bugs)
|
||||
if (build < 10000) {
|
||||
return "Outlook 2016 (MSI / Volume License)";
|
||||
}
|
||||
// Build >= 10000 = Click-to-Run (Retail 2016 / 2019 / 365)
|
||||
// These render well (SVG support, modern CSS)
|
||||
return "Outlook 365 / 2019+ (Modern)";
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback for 'Outlook Express' or 'New Outlook' (Browser)
|
||||
return name;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getDeviceVendor,
|
||||
isAppleSilicon,
|
||||
@@ -64,5 +108,6 @@ module.exports = {
|
||||
isElectron,
|
||||
isFromEU,
|
||||
isFrozenUA,
|
||||
isStandalonePWA
|
||||
isStandalonePWA,
|
||||
getOutlookEdition
|
||||
}
|
||||
@@ -59,6 +59,50 @@ const isFromEU = _isFromEU;
|
||||
*/
|
||||
const isStandalonePWA = _isStandalonePWA;
|
||||
|
||||
/**
|
||||
* Translates a raw Outlook User-Agent name/version into a
|
||||
* Developer-friendly Edition (e.g., "Outlook 2019 (Modern Word)").
|
||||
*/
|
||||
const getOutlookEdition = (name, version) => {
|
||||
if (!name || !version) return name;
|
||||
const cleanName = name.toLowerCase().replace(/microsoft\s+/, '');
|
||||
|
||||
// 1. Handle Mac Separately (Different Rendering Engine)
|
||||
if (cleanName === 'macoutlook') {
|
||||
const major = parseInt(version.split('.')[0], 10);
|
||||
if (major >= 16) return "Outlook for Mac (Modern)";
|
||||
return "Outlook for Mac (Legacy)";
|
||||
}
|
||||
|
||||
// 2. Handle Windows Outlook
|
||||
if (cleanName === 'outlook') {
|
||||
const parts = version.split('.').map(Number);
|
||||
const major = parts[0];
|
||||
const build = parts[2] || 0; // Build number is usually the 3rd part
|
||||
|
||||
// Pre-2016 Versions (Clear Major Version mapping)
|
||||
if (major === 15) return "Outlook 2013";
|
||||
if (major === 14) return "Outlook 2010";
|
||||
if (major === 12) return "Outlook 2007";
|
||||
if (major < 12) return "Outlook (Legacy)";
|
||||
|
||||
// The Version 16.0 Confusion
|
||||
if (major === 16) {
|
||||
// Build < 10000 = MSI (Volume License 2016/2019)
|
||||
// These render poorly (No SVG, older bugs)
|
||||
if (build < 10000) {
|
||||
return "Outlook 2016 (MSI / Volume License)";
|
||||
}
|
||||
// Build >= 10000 = Click-to-Run (Retail 2016 / 2019 / 365)
|
||||
// These render well (SVG support, modern CSS)
|
||||
return "Outlook 365 / 2019+ (Modern)";
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fallback for 'Outlook Express' or 'New Outlook' (Browser)
|
||||
return name;
|
||||
};
|
||||
|
||||
export {
|
||||
getDeviceVendor,
|
||||
isAppleSilicon,
|
||||
@@ -68,5 +112,6 @@ export {
|
||||
isElectron,
|
||||
isFromEU,
|
||||
isFrozenUA,
|
||||
isStandalonePWA
|
||||
isStandalonePWA,
|
||||
getOutlookEdition
|
||||
}
|
||||
Reference in New Issue
Block a user