Skip to content

Commit

Permalink
feat: add qq browser support (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
pure-js committed Aug 22, 2023
1 parent 48df8cb commit f3d6b0a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 76 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![codecov](https://codecov.io/gh/pure-js/browser-detection/branch/master/graph/badge.svg)](https://codecov.io/gh/pure-js/browser-detection)

Browser detection using the user agent.
Tested on most popular browser in the World on October 2017, statistic gets from StatCounter.
Tested on most popular browser in the World on October 2017 (and updated on July 2023), statistic gets from StatCounter.

> It's worth re-iterating: it's very rarely a good idea to use user agent sniffing. You can almost always find a better, more broadly compatible way to solve your problem!
>
Expand Down
58 changes: 36 additions & 22 deletions src/browser-detection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ describe('Should correctly detect name & version of', () => {
});
});

test('Samsung Internet', () => {
const samsung = {
userAgent: `Mozilla/5.0 (Linux; Android 5.1.1;
SAMSUNG SM-G360T1 Build/LMY47X)
AppleWebKit/537.36 (KHTML, like Gecko)
SamsungBrowser/3.3 Chrome/38.0.2125.102 Mobile Safari/537.36`,
};

expect(detectBrowserNameAndVersion(samsung)).toEqual({
name: 'Samsung Internet',
version: 3,
});
});

test('UC Browser', () => {
const ucBrowser = {
userAgent: `UCWEB/2.0 (Java; U; MIDP-2.0; Nokia203/20.37)
Expand Down Expand Up @@ -93,16 +107,17 @@ describe('Should correctly detect name & version of', () => {
});
});

test('Internet Explorer', () => {
const ie = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; WOW64;
Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727;
.NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko`,
test('QQ Browser', () => {
const qqbrowser = {
userAgent: `Mozilla/5.0 (Linux; U; Android 11; zh-cn; 21091116UC Build/RP1A.200720.011)
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0
Chrome/66.0.3359.126 MQQBrowser/10.8 Mobile Safari/537.36`,
};

expect(detectBrowserNameAndVersion(ie)).toEqual({
name: 'IE',
version: 11,
expect(detectBrowserNameAndVersion(qqbrowser)).toEqual({
name: 'QQ Browser',
// Version: 10.8, // TODO: add version after dot
version: 10,
});
});

Expand All @@ -121,20 +136,6 @@ describe('Should correctly detect name & version of', () => {
});
});

test('Samsung Internet', () => {
const samsung = {
userAgent: `Mozilla/5.0 (Linux; Android 5.1.1;
SAMSUNG SM-G360T1 Build/LMY47X)
AppleWebKit/537.36 (KHTML, like Gecko)
SamsungBrowser/3.3 Chrome/38.0.2125.102 Mobile Safari/537.36`,
};

expect(detectBrowserNameAndVersion(samsung)).toEqual({
name: 'Samsung Internet',
version: 3,
});
});

test('Android browser', () => {
const android = {
userAgent: `Mozilla/5.0 (Linux; U; Android 4.0.4;
Expand All @@ -160,6 +161,19 @@ describe('Should correctly detect name & version of', () => {
version: 15,
});
});

test('Internet Explorer', () => {
const ie = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; WOW64;
Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727;
.NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko`,
};

expect(detectBrowserNameAndVersion(ie)).toEqual({
name: 'IE',
version: 11,
});
});
});

describe('Should not fail', () => {
Expand Down
113 changes: 60 additions & 53 deletions src/browser-detection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
function isChrome(userAgent: string): boolean {
return userAgent.includes('Chrome')
&& !userAgent.includes('Chromium')
&& !userAgent.includes('SamsungBrowser')
&& !userAgent.includes('OPR')
&& !userAgent.includes('Edge')
&& !userAgent.includes('SamsungBrowser');
&& !userAgent.includes('MQQBrowser')
&& !userAgent.includes('Edge');
}

/**
Expand All @@ -20,24 +21,10 @@ function isSafari(userAgent: string): boolean {
}

/**
* Detects UC browser
*/
function isUcBrowser(userAgent: string): boolean {
return userAgent.includes('UCBrowser');
}

/**
* Detects Firefox browser
*/
function isFirefox(userAgent: string): boolean {
return userAgent.includes('Firefox') && !userAgent.includes('Seamonkey');
}

/**
* Detects IE browser
* Detects Samsung browser
*/
function isIe(userAgent: string): boolean {
return (/trident/i.test(userAgent));
function isSamsungInternet(userAgent: string): boolean {
return userAgent.includes('SamsungBrowser');
}

/**
Expand All @@ -48,10 +35,10 @@ function isOpera(userAgent: string): boolean {
}

/**
* Detects Samsung browser
* Detects UC browser
*/
function isSamsungInternet(userAgent: string): boolean {
return userAgent.includes('SamsungBrowser');
function isUcBrowser(userAgent: string): boolean {
return userAgent.includes('UCBrowser');
}

/**
Expand All @@ -63,7 +50,28 @@ function isAndroidBrowser(userAgent: string): boolean {
&& userAgent.includes('AppleWebKit');
}

export type BrowserName = 'Chrome' | 'Safari' | 'UC Browser' | 'Firefox' | 'IE' | 'Opera' | 'Samsung Internet' | 'Android Browser' | 'Edge';
/**
* Detects Firefox browser
*/
function isFirefox(userAgent: string): boolean {
return userAgent.includes('Firefox') && !userAgent.includes('Seamonkey');
}

/**
* Detects QQ browser
*/
function isQqBrowser(userAgent: string): boolean {
return userAgent.includes('MQQBrowser');
}

/**
* Detects IE browser
*/
function isIe(userAgent: string): boolean {
return (/trident/i.test(userAgent));
}

export type BrowserName = 'Chrome' | 'Safari' | 'Samsung Internet' | 'Opera' | 'UC Browser' | 'Android Browser' | 'Firefox' | 'QQ Browser' | 'Edge' | 'IE';

/**
* Detects Edge browser
Expand All @@ -74,8 +82,6 @@ function isEdge(userAgent: string): boolean {

/**
* Detects browser name
* @param {string} userAgent - window.navigator
* @return {string} browser name
*/
function detectBrowserName(userAgent: string): BrowserName | undefined {
if (isChrome(userAgent)) {
Expand All @@ -86,44 +92,48 @@ function detectBrowserName(userAgent: string): BrowserName | undefined {
return 'Safari';
}

if (isUcBrowser(userAgent)) {
return 'UC Browser';
}

if (isFirefox(userAgent)) {
return 'Firefox';
}

if (isIe(userAgent)) {
return 'IE';
if (isSamsungInternet(userAgent)) {
return 'Samsung Internet';
}

if (isOpera(userAgent)) {
return 'Opera';
}

if (isSamsungInternet(userAgent)) {
return 'Samsung Internet';
if (isUcBrowser(userAgent)) {
return 'UC Browser';
}

if (isAndroidBrowser(userAgent)) {
return 'Android Browser';
}

if (isFirefox(userAgent)) {
return 'Firefox';
}

if (isQqBrowser(userAgent)) {
return 'QQ Browser';
}

if (isEdge(userAgent)) {
return 'Edge';
}

if (isIe(userAgent)) {
return 'IE';
}

return undefined;
}

/**
* Retrieve browser version
*/
function retrieveVersion(name: string, str: string): number {
name += '/';
const start = str.indexOf(name);
let preNum = str.substring(start + name.length);
function retrieveVersion(browserName: string, userAgent: string): number {
const name = `${browserName}/`;
const start = userAgent.indexOf(name);
let preNum = userAgent.substring(start + name.length);
const index = preNum.indexOf(' ');
if (index > 0) {
preNum = preNum.substring(0, index);
Expand All @@ -141,29 +151,26 @@ function retrieveVersion(name: string, str: string): number {
return Number(num);
}

export type UaBrowserName = 'SamsungBrowser' | 'OPR' | 'UCBrowser' | 'MQQBrowser';

/**
* Returns Association
*/
function getBeautifulName(name: BrowserName | undefined): string | undefined {
let browserName;

function getBrowserUaName(name: BrowserName | undefined): UaBrowserName | undefined {
if (name) {
switch (name) {
case 'Opera':
browserName = 'OPR';
break;
return 'OPR';
case 'UC Browser':
browserName = 'UCBrowser';
break;
return 'UCBrowser';
case 'Samsung Internet':
browserName = 'SamsungBrowser';
break;
return 'SamsungBrowser';
case 'QQ Browser':
return 'MQQBrowser';
default:
return undefined;
}
}

return browserName;
}

/**
Expand All @@ -189,7 +196,7 @@ function detectBrowserVersion(nav: {
}
}

const browserName = getBeautifulName(name);
const browserName = getBrowserUaName(name);

if (browserName) {
return retrieveVersion(browserName, userAgent);
Expand Down

0 comments on commit f3d6b0a

Please sign in to comment.