Move feature detection into its own method: withFeatureCheck

This commit is contained in:
Faisal Salman 2023-04-09 05:34:02 +07:00
parent 05747dba37
commit 16b416d9ea
5 changed files with 91 additions and 37 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
node_modules/ node_modules/
npm-debug.log npm-debug.log
playwright-report/ playwright-report/
test-results/
### vim ### ### vim ###
.*.s[a-w][a-z] .*.s[a-w][a-z]

View File

@ -7,6 +7,7 @@
- What's new: - What's new:
- Add some new methods in result object: - Add some new methods in result object:
- Add support for client hints: `withClientHints()` - Add support for client hints: `withClientHints()`
- Add support for feature detection: `withFeatureCheck()`
- Utility for easy comparison: `is()` - Utility for easy comparison: `is()`
- Utility to print full-name: `toString()` - Utility to print full-name: `toString()`
- Add support for ES module `import { UAParser } from 'ua-parser-js'` - Add support for ES module `import { UAParser } from 'ua-parser-js'`

View File

@ -346,6 +346,21 @@ new UAParser(request.headers)
}); });
``` ```
#### * `withFeatureCheck():object` `since@2.0`
This method allows us to examine other features beyond `navigator.userAgent` to further improve detection of the following:
- browser : Brave (check for `navigator.isBrave`)
- device : iPad (check for `navigator.standalone` & `navigator.maxTouchPoints`)
```js
// suppose this code runs on iPad
const withoutFeatureCheck = UAParser();
const withFeatureCheck = UAParser().withFeatureCheck();
console.log(withoutFeatureCheck.device); // { vendor : "Apple", model : "Macintosh", type : undefined }
console.log(withFeatureCheck.device); // { vendor : "Apple", model : "iPad", type : "tablet" }
```
## Extending Regex ## Extending Regex
If you want to detect something that's not currently provided by UAParser.js (eg: `bots`, specific apps, etc), you can pass a list of regexes to extend internal UAParser.js regexes with your own. If you want to detect something that's not currently provided by UAParser.js (eg: `bots`, specific apps, etc), you can pass a list of regexes to extend internal UAParser.js regexes with your own.

View File

@ -862,6 +862,10 @@
}); });
}; };
UAParserData.prototype.withFeatureCheck = function () {
return item.detectFeature().get();
};
if (itemType != UA_RESULT) { if (itemType != UA_RESULT) {
UAParserData.prototype.is = function (strToCheck) { UAParserData.prototype.is = function (strToCheck) {
var is = false; var is = false;
@ -978,6 +982,20 @@
if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) { if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
this.set(NAME, NAVIGATOR_UADATA[PLATFORM]); this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
} }
break;
case UA_RESULT:
var data = this.data;
var detect = function (itemType) {
return data[itemType]
.getItem()
.detectFeature()
.get();
};
this.set(UA_BROWSER, detect(UA_BROWSER))
.set(UA_CPU, detect(UA_CPU))
.set(UA_DEVICE, detect(UA_DEVICE))
.set(UA_ENGINE, detect(UA_ENGINE))
.set(UA_OS, detect(UA_OS));
} }
} }
return this; return this;
@ -1046,8 +1064,7 @@
.parseCH() .parseCH()
.get(); .get();
}; };
this.set('ua', ua) this.set(UA_BROWSER, parse(UA_BROWSER))
.set(UA_BROWSER, parse(UA_BROWSER))
.set(UA_CPU, parse(UA_CPU)) .set(UA_CPU, parse(UA_CPU))
.set(UA_DEVICE, parse(UA_DEVICE)) .set(UA_DEVICE, parse(UA_DEVICE))
.set(UA_ENGINE, parse(UA_ENGINE)) .set(UA_ENGINE, parse(UA_ENGINE))
@ -1118,7 +1135,6 @@
return function () { return function () {
return new UAParserItem(itemType, userAgent, regexMap[itemType], HTTP_UACH) return new UAParserItem(itemType, userAgent, regexMap[itemType], HTTP_UACH)
.parseUA() .parseUA()
.detectFeature()
.get(); .get();
}; };
} }

View File

@ -3,6 +3,8 @@ import { test, expect } from '@playwright/test';
import path from 'path'; import path from 'path';
import url from 'url'; import url from 'url';
const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../')}/dist/ua-parser.html`;
test('read client hints data', async ({ page }) => { test('read client hints data', async ({ page }) => {
await page.addInitScript(() => { await page.addInitScript(() => {
Object.defineProperty(navigator, 'userAgentData', { Object.defineProperty(navigator, 'userAgentData', {
@ -33,8 +35,7 @@ test('read client hints data', async ({ page }) => {
}); });
}); });
const dirname = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../'); await page.goto(localHtml);
await page.goto(`file://${dirname}/dist/ua-parser.html`);
// @ts-ignore // @ts-ignore
const uap = await page.evaluate(async () => await UAParser().withClientHints()); const uap = await page.evaluate(async () => await UAParser().withClientHints());
@ -42,3 +43,23 @@ test('read client hints data', async ({ page }) => {
expect(uap).toHaveProperty('browser.name', 'New Browser'); expect(uap).toHaveProperty('browser.name', 'New Browser');
expect(uap).toHaveProperty('os.name', 'New OS'); expect(uap).toHaveProperty('os.name', 'New OS');
}); });
test('detect Brave', async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(navigator, 'brave', {
value: {
isBrave: () => true
}
});
});
await page.goto(localHtml);
// @ts-ignore
let uap = await page.evaluate(() => UAParser());
expect(uap).toHaveProperty('browser.name', 'Chrome Headless');
// @ts-ignore
uap = await page.evaluate(() => UAParser().withFeatureCheck());
expect(uap).toHaveProperty('browser.name', 'Brave');
});