support for desktop versions #20

This commit is contained in:
undergroundwires
2020-07-25 21:26:01 +01:00
parent 4ff4b52202
commit 04b9b59e14
33 changed files with 3919 additions and 132 deletions

View File

@@ -0,0 +1,54 @@
import { OperatingSystem } from '../OperatingSystem';
import { DetectorBuilder } from './DetectorBuilder';
import { IBrowserOsDetector } from './IBrowserOsDetector';
export class BrowserOsDetector implements IBrowserOsDetector {
private readonly detectors = BrowserDetectors;
public detect(userAgent: string): OperatingSystem {
if (!userAgent) {
return OperatingSystem.Unknown;
}
for (const detector of this.detectors) {
const os = detector.detect(userAgent);
if (os !== OperatingSystem.Unknown) {
return os;
}
}
return OperatingSystem.Unknown;
}
}
// Reference: https://github.com/keithws/browser-report/blob/master/index.js#L304
const BrowserDetectors =
[
define(OperatingSystem.KaiOS, (b) =>
b.mustInclude('KAIOS')),
define(OperatingSystem.ChromeOS, (b) =>
b.mustInclude('CrOS')),
define(OperatingSystem.BlackBerryOS, (b) =>
b.mustInclude('BlackBerry')),
define(OperatingSystem.BlackBerryTabletOS, (b) =>
b.mustInclude('RIM Tablet OS')),
define(OperatingSystem.BlackBerry, (b) =>
b.mustInclude('BB10')),
define(OperatingSystem.Android, (b) =>
b.mustInclude('Android').mustNotInclude('Windows Phone')),
define(OperatingSystem.Android, (b) =>
b.mustInclude('Adr').mustNotInclude('Windows Phone')),
define(OperatingSystem.iOS, (b) =>
b.mustInclude('like Mac OS X')),
define(OperatingSystem.Linux, (b) =>
b.mustInclude('Linux').mustNotInclude('Android').mustNotInclude('Adr')),
define(OperatingSystem.Windows, (b) =>
b.mustInclude('Windows').mustNotInclude('Windows Phone')),
define(OperatingSystem.WindowsPhone, (b) =>
b.mustInclude('Windows Phone')),
define(OperatingSystem.macOS, (b) =>
b.mustInclude('OS X').mustNotInclude('Android').mustNotInclude('like Mac OS X')),
];
function define(os: OperatingSystem, applyRules: (builder: DetectorBuilder) => DetectorBuilder): IBrowserOsDetector {
const builder = new DetectorBuilder(os);
applyRules(builder);
return builder.build();
}

View File

@@ -0,0 +1,49 @@
import { IBrowserOsDetector } from './IBrowserOsDetector';
import { OperatingSystem } from '../OperatingSystem';
export class DetectorBuilder {
private readonly existingPartsInUserAgent = new Array<string>();
private readonly notExistingPartsInUserAgent = new Array<string>();
constructor(private readonly os: OperatingSystem) { }
public mustInclude(str: string): DetectorBuilder {
if (!str) {
throw new Error('part to include is empty or undefined');
}
this.existingPartsInUserAgent.push(str);
return this;
}
public mustNotInclude(str: string): DetectorBuilder {
if (!str) {
throw new Error('part to not include is empty or undefined');
}
this.notExistingPartsInUserAgent.push(str);
return this;
}
public build(): IBrowserOsDetector {
if (!this.existingPartsInUserAgent.length) {
throw new Error('Must include at least a part');
}
return {
detect: (userAgent) => {
if (!userAgent) {
throw new Error('User agent is null or undefined');
}
for (const exitingPart of this.existingPartsInUserAgent) {
if (!userAgent.includes(exitingPart)) {
return OperatingSystem.Unknown;
}
}
for (const notExistingPart of this.notExistingPartsInUserAgent) {
if (userAgent.includes(notExistingPart)) {
return OperatingSystem.Unknown;
}
}
return this.os;
},
};
}
}

View File

@@ -0,0 +1,5 @@
import { OperatingSystem } from '../OperatingSystem';
export interface IBrowserOsDetector {
detect(userAgent: string): OperatingSystem;
}