Skip to content

Commit f0097de

Browse files
committed
fix: improve unhighlightable contents check
1 parent f71acd4 commit f0097de

File tree

1 file changed

+187
-106
lines changed

1 file changed

+187
-106
lines changed

navigator/src/helpers/sML.ts

Lines changed: 187 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -11,133 +11,214 @@
1111
/// <reference types="user-agent-data-types" />
1212

1313
declare interface OSFlags {
14-
iOS: number[];
15-
macOS: number[];
16-
iPadOS: number[];
17-
WindowsPhone: number[];
18-
ChromeOS: number[];
19-
Windows: number[];
20-
Android: number[];
21-
Linux: number[];
22-
Firefox: boolean;
14+
iOS: number[];
15+
macOS: number[];
16+
iPadOS: number[];
17+
WindowsPhone: number[];
18+
ChromeOS: number[];
19+
Windows: number[];
20+
Android: number[];
21+
Linux: number[];
22+
Firefox: boolean;
2323
}
2424

2525
declare interface UAFlags {
26-
Gecko: number[];
27-
Firefox: number[];
28-
Waterfox: number[];
29-
Opera: number[];
30-
Silk: number[];
31-
Blink: number[];
32-
EdgeHTML: number[];
33-
Chrome: number[];
34-
Chromium: number[];
35-
Phoebe: number[];
36-
UCBrowser: number[];
37-
Vivaldi: number[];
38-
Safari: number[];
39-
Edge: number[];
40-
WebKit: number[];
41-
Trident: number[];
42-
InternetExplorer: number[];
43-
Flash: number[];
44-
Facebook: number[];
45-
LINE: number[];
26+
Gecko: number[];
27+
Firefox: number[];
28+
Waterfox: number[];
29+
Opera: number[];
30+
Silk: number[];
31+
Blink: number[];
32+
EdgeHTML: number[];
33+
Chrome: number[];
34+
Chromium: number[];
35+
Phoebe: number[];
36+
UCBrowser: number[];
37+
Vivaldi: number[];
38+
Safari: number[];
39+
Edge: number[];
40+
WebKit: number[];
41+
Trident: number[];
42+
InternetExplorer: number[];
43+
Flash: number[];
44+
Facebook: number[];
45+
LINE: number[];
4646
}
4747

4848
declare type iOSRequest = "mobile" | "desktop" | undefined;
4949

5050
// Fallback when global 'navigator' is not available, such as in SSR environments.
51-
const userAgent = () => typeof navigator === "undefined" ? "" : (navigator.userAgent || "");
52-
const userAgentData = () => typeof navigator === "undefined" ? undefined : (navigator.userAgentData || undefined);
51+
const userAgent = () =>
52+
typeof navigator === "undefined" ? "" : navigator.userAgent || "";
53+
const userAgentData = () =>
54+
typeof navigator === "undefined"
55+
? undefined
56+
: navigator.userAgentData || undefined;
5357

5458
class sMLFactory {
55-
OS: OSFlags;
56-
UA: UAFlags;
57-
Env!: string[];
59+
OS: OSFlags;
60+
UA: UAFlags;
61+
Env!: string[];
5862

59-
constructor() {
60-
const NUAD = userAgentData(), NUA = userAgent();
63+
constructor() {
64+
const NUAD = userAgentData(),
65+
NUA = userAgent();
6166

62-
const _sV = (V?: string | number) => (typeof V === "string" || typeof V === "number") && V ? String(V).replace(/_/g, ".").split(".").map(I => parseInt(I) || 0) : [];
63-
const _dV = (Pre="") => {
64-
if(!Pre) return [];
65-
const RE = new RegExp("^.*" + Pre + "[ :\\/]?(\\d+([\\._]\\d+)*).*$");
66-
if(!RE.test(NUA)) return [];
67-
return _sV(NUA.replace(RE, "$1"));
68-
};
67+
const _sV = (V?: string | number) =>
68+
(typeof V === "string" || typeof V === "number") && V
69+
? String(V)
70+
.replace(/_/g, ".")
71+
.split(".")
72+
.map((I) => parseInt(I) || 0)
73+
: [];
74+
const _dV = (Pre = "") => {
75+
if (!Pre) return [];
76+
const RE = new RegExp("^.*" + Pre + "[ :\\/]?(\\d+([\\._]\\d+)*).*$");
77+
if (!RE.test(NUA)) return [];
78+
return _sV(NUA.replace(RE, "$1"));
79+
};
6980

70-
this.OS = ((OS: OSFlags) => {
71-
if( /(macOS|Mac OS X)/.test(NUA)) {
72-
if(/\(iP(hone|od touch);/.test(NUA)) OS.iOS = _dV("CPU (?:iPhone )?OS ");
73-
if( /\(iPad;/.test(NUA)) OS.iOS = OS.iPadOS = _dV("CPU (?:iPhone )?OS ");
74-
else if( /(macOS|Mac OS X) \d/.test(NUA)) document.ontouchend !== undefined ? OS.iOS = OS.iPadOS = _dV() : OS.macOS = _dV("(?:macOS|Mac OS X) ");
75-
} else if( /Windows( NT)? \d/.test(NUA)) OS.Windows = (V => V[0] !== 6 || !V[1] ? V : V[1] === 1 ? [7] : V[1] === 2 ? [8] : [8, 1])(_dV("Windows(?: NT)?"));
76-
else if( /Android \d/.test(NUA)) OS.Android = _dV("Android");
77-
else if( /CrOS/.test(NUA)) OS.ChromeOS = _dV();
78-
else if( /X11;/.test(NUA)) OS.Linux = _dV();
79-
return OS;
80-
})({} as OSFlags); if(NUAD) NUAD.getHighEntropyValues(["architecture", "model", "platform", "platformVersion", "uaFullVersion"]).then((HEUAD: any) => (OS => { const Pf = HEUAD.platform, PfV = HEUAD.platformVersion; if(!Pf || !PfV) return;
81-
if( /^i(OS|P(hone|od touch))$/.test(Pf)) OS.iOS = _sV(PfV);
82-
else if( /^iPad(OS)?$/.test(Pf)) OS.iOS = OS.iPadOS = _sV(PfV);
83-
else if(/^(macOS|(Mac )?OS X|Mac(Intel)?)$/.test(Pf)) document.ontouchend !== undefined ? OS.iOS = OS.iPadOS = _sV() : OS.macOS = _sV(PfV);
84-
else if( /^(Microsoft )?Windows$/.test(Pf)) OS.Windows = _sV(PfV);
85-
else if( /^(Google )?Android$/.test(Pf)) OS.Android = _sV(PfV);
86-
else if( /^((Google )?Chrome OS|CrOS)$/.test(Pf)) OS.ChromeOS = _sV(PfV);
87-
else if( /^(Linux|Ubuntu|X11)$/.test(Pf)) OS.Linux = _sV(PfV);
88-
else return; /**/ Object.keys(this.OS).forEach(Key => delete (this.OS as any)[Key]), Object.assign(this.OS, OS);
89-
})({} as OSFlags));
81+
this.OS = ((OS: OSFlags) => {
82+
if (/(macOS|Mac OS X)/.test(NUA)) {
83+
if (/\(iP(hone|od touch);/.test(NUA))
84+
OS.iOS = _dV("CPU (?:iPhone )?OS ");
85+
if (/\(iPad;/.test(NUA))
86+
OS.iOS = OS.iPadOS = _dV("CPU (?:iPhone )?OS ");
87+
else if (/(macOS|Mac OS X) \d/.test(NUA))
88+
document.ontouchend !== undefined
89+
? (OS.iOS = OS.iPadOS = _dV())
90+
: (OS.macOS = _dV("(?:macOS|Mac OS X) "));
91+
} else if (/Windows( NT)? \d/.test(NUA))
92+
OS.Windows = ((V) =>
93+
V[0] !== 6 || !V[1]
94+
? V
95+
: V[1] === 1
96+
? [7]
97+
: V[1] === 2
98+
? [8]
99+
: [8, 1])(_dV("Windows(?: NT)?"));
100+
else if (/Android \d/.test(NUA)) OS.Android = _dV("Android");
101+
else if (/CrOS/.test(NUA)) OS.ChromeOS = _dV();
102+
else if (/X11;/.test(NUA)) OS.Linux = _dV();
103+
return OS;
104+
})({} as OSFlags);
105+
if (NUAD)
106+
NUAD.getHighEntropyValues([
107+
"architecture",
108+
"model",
109+
"platform",
110+
"platformVersion",
111+
"uaFullVersion",
112+
]).then((HEUAD: any) =>
113+
((OS) => {
114+
const Pf = HEUAD.platform,
115+
PfV = HEUAD.platformVersion;
116+
if (!Pf || !PfV) return;
117+
if (/^i(OS|P(hone|od touch))$/.test(Pf)) OS.iOS = _sV(PfV);
118+
else if (/^iPad(OS)?$/.test(Pf)) OS.iOS = OS.iPadOS = _sV(PfV);
119+
else if (/^(macOS|(Mac )?OS X|Mac(Intel)?)$/.test(Pf))
120+
document.ontouchend !== undefined
121+
? (OS.iOS = OS.iPadOS = _sV())
122+
: (OS.macOS = _sV(PfV));
123+
else if (/^(Microsoft )?Windows$/.test(Pf)) OS.Windows = _sV(PfV);
124+
else if (/^(Google )?Android$/.test(Pf)) OS.Android = _sV(PfV);
125+
else if (/^((Google )?Chrome OS|CrOS)$/.test(Pf))
126+
OS.ChromeOS = _sV(PfV);
127+
else if (/^(Linux|Ubuntu|X11)$/.test(Pf)) OS.Linux = _sV(PfV);
128+
else return;
129+
/**/ Object.keys(this.OS).forEach(
130+
(Key) => delete (this.OS as any)[Key]
131+
),
132+
Object.assign(this.OS, OS);
133+
})({} as OSFlags)
134+
);
90135

91-
this.UA = ((UA: UAFlags) => { let _OK = false;
92-
if(NUAD && Array.isArray(NUAD.brands)) { const BnV = NUAD.brands.reduce((BnV: Record<string, number[]>, _: NavigatorUABrandVersion) => { BnV[_.brand] = [(_.version as any) * 1]; return BnV; }, {});
93-
if(BnV["Google Chrome"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Chrome = BnV["Google Chrome"];
94-
else if(BnV["Microsoft Edge"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Edge = BnV["Microsoft Edge"];
95-
else if(BnV["Opera"]) _OK = true, UA.Blink = UA.Chromium = BnV["Chromium"] || [], UA.Opera = BnV["Opera"];
96-
} if(!_OK) {
97-
if( / Gecko\/\d/.test(NUA)) { UA.Gecko = _dV("rv");
98-
if( / Waterfox\/\d/.test(NUA)) UA.Waterfox = _dV("Waterfox");
99-
else if( / Firefox\/\d/.test(NUA)) UA.Firefox = _dV("Firefox");
100-
} else if( / Edge\/\d/.test(NUA)) { UA.EdgeHTML = _dV("Edge");
101-
UA.Edge = UA.EdgeHTML;
102-
} else if(/ Chrom(ium|e)\/\d/.test(NUA)) { UA.Blink = UA.Chromium = (V => V[0] ? V : _dV("Chrome"))(_dV("Chromium"));
103-
if( / EdgA?\/\d/.test(NUA)) UA.Edge = (V => V[0] ? V : _dV("Edg"))(_dV("EdgA"));
104-
else if( / OPR\/\d/.test(NUA)) UA.Opera = _dV("OPR");
105-
else if( / Vivaldi\/\d/.test(NUA)) UA.Vivaldi = _dV("Vivaldi");
106-
else if( / Silk\/\d/.test(NUA)) UA.Silk = _dV("Silk");
107-
else if( / UCBrowser\/\d/.test(NUA)) UA.UCBrowser = _dV("UCBrowser");
108-
else if( / Phoebe\/\d/.test(NUA)) UA.Phoebe = _dV("Phoebe");
109-
else UA.Chrome = (V => V[0] ? V : UA.Chromium)(_dV("Chrome"));
110-
} else if( / AppleWebKit\/\d/.test(NUA)) { UA.WebKit = _dV("AppleWebKit");
111-
if( / CriOS \d/.test(NUA)) UA.Chrome = _dV("CriOS");
112-
else if( / FxiOS \d/.test(NUA)) UA.Firefox = _dV("FxiOS");
113-
else if( / EdgiOS\/\d/.test(NUA)) UA.Edge = _dV("EdgiOS");
114-
else if( / Version\/\d/.test(NUA)) UA.Safari = _dV("Version");
115-
} else if( / Trident\/\d/.test(NUA)) { UA.Trident = _dV("Trident");
116-
UA.InternetExplorer = (V => V[0] ? V : _dV("MSIE"))(_dV("rv"));
117-
}
118-
} /*+*/ if( /[\[; ]FB(AN|_IAB)\//.test(NUA)) UA.Facebook = _dV("FBAV");
119-
/*+*/ if( / Line\/\d/.test(NUA)) UA.LINE = _dV("Line");
120-
return UA;
121-
})({} as UAFlags);
136+
this.UA = ((UA: UAFlags) => {
137+
let _OK = false;
138+
if (NUAD && Array.isArray(NUAD.brands)) {
139+
const BnV = NUAD.brands.reduce(
140+
(BnV: Record<string, number[]>, _: NavigatorUABrandVersion) => {
141+
BnV[_.brand] = [(_.version as any) * 1];
142+
return BnV;
143+
},
144+
{}
145+
);
146+
if (BnV["Google Chrome"])
147+
(_OK = true),
148+
(UA.Blink = UA.Chromium = BnV["Chromium"] || []),
149+
(UA.Chrome = BnV["Google Chrome"]);
150+
else if (BnV["Microsoft Edge"])
151+
(_OK = true),
152+
(UA.Blink = UA.Chromium = BnV["Chromium"] || []),
153+
(UA.Edge = BnV["Microsoft Edge"]);
154+
else if (BnV["Opera"])
155+
(_OK = true),
156+
(UA.Blink = UA.Chromium = BnV["Chromium"] || []),
157+
(UA.Opera = BnV["Opera"]);
158+
}
159+
if (!_OK) {
160+
if (/ Gecko\/\d/.test(NUA)) {
161+
UA.Gecko = _dV("rv");
162+
if (/ Waterfox\/\d/.test(NUA)) UA.Waterfox = _dV("Waterfox");
163+
else if (/ Firefox\/\d/.test(NUA)) UA.Firefox = _dV("Firefox");
164+
} else if (/ Edge\/\d/.test(NUA)) {
165+
UA.EdgeHTML = _dV("Edge");
166+
UA.Edge = UA.EdgeHTML;
167+
} else if (/ Chrom(ium|e)\/\d/.test(NUA)) {
168+
UA.Blink = UA.Chromium = ((V) => (V[0] ? V : _dV("Chrome")))(
169+
_dV("Chromium")
170+
);
171+
if (/ EdgA?\/\d/.test(NUA))
172+
UA.Edge = ((V) => (V[0] ? V : _dV("Edg")))(_dV("EdgA"));
173+
else if (/ OPR\/\d/.test(NUA)) UA.Opera = _dV("OPR");
174+
else if (/ Vivaldi\/\d/.test(NUA)) UA.Vivaldi = _dV("Vivaldi");
175+
else if (/ Silk\/\d/.test(NUA)) UA.Silk = _dV("Silk");
176+
else if (/ UCBrowser\/\d/.test(NUA)) UA.UCBrowser = _dV("UCBrowser");
177+
else if (/ Phoebe\/\d/.test(NUA)) UA.Phoebe = _dV("Phoebe");
178+
else UA.Chrome = ((V) => (V[0] ? V : UA.Chromium))(_dV("Chrome"));
179+
} else if (/ AppleWebKit\/\d/.test(NUA)) {
180+
UA.WebKit = _dV("AppleWebKit");
181+
if (/ CriOS \d/.test(NUA)) UA.Chrome = _dV("CriOS");
182+
else if (/ FxiOS \d/.test(NUA)) UA.Firefox = _dV("FxiOS");
183+
else if (/ EdgiOS\/\d/.test(NUA)) UA.Edge = _dV("EdgiOS");
184+
else if (/ Version\/\d/.test(NUA)) UA.Safari = _dV("Version");
185+
} else if (/ Trident\/\d/.test(NUA)) {
186+
UA.Trident = _dV("Trident");
187+
UA.InternetExplorer = ((V) => (V[0] ? V : _dV("MSIE")))(_dV("rv"));
188+
}
189+
}
190+
/*+*/ if (/[\[; ]FB(AN|_IAB)\//.test(NUA)) UA.Facebook = _dV("FBAV");
191+
/*+*/ if (/ Line\/\d/.test(NUA)) UA.LINE = _dV("Line");
192+
return UA;
193+
})({} as UAFlags);
122194

123-
(this.Env as any) = { get: () => [this.OS, this.UA].reduce((Env: string[], OS_UA) => { for(const Par in OS_UA) if((OS_UA as any)[Par]) Env.push(Par); return Env; }, []) };
124-
}
195+
(this.Env as any) = {
196+
get: () =>
197+
[this.OS, this.UA].reduce((Env: string[], OS_UA) => {
198+
for (const Par in OS_UA) if ((OS_UA as any)[Par]) Env.push(Par);
199+
return Env;
200+
}, []),
201+
};
202+
}
125203
}
126204

127205
class sMLFactoryWithRequest extends sMLFactory {
128-
get iOSRequest(): iOSRequest {
129-
const NUAD = userAgentData(), NUA = userAgent();
206+
get iOSRequest(): iOSRequest {
207+
const NUAD = userAgentData(),
208+
NUA = userAgent();
130209

131-
if (this.OS.iOS && !this.OS.iPadOS) {
132-
return "mobile";
133-
} else if (this.OS.iPadOS) {
134-
return (/\(iPad;/.test(NUA) || (NUAD && /^iPad(OS)?$/.test(NUAD.platform))) ? "mobile" : "desktop"
135-
}
136-
137-
return undefined;
210+
if (this.OS.iOS && !this.OS.iPadOS) {
211+
return "mobile";
212+
} else if (this.OS.iPadOS) {
213+
return /\(iPad;/.test(NUA) || (NUAD && /^iPad(OS)?$/.test(NUAD.platform))
214+
? "mobile"
215+
: "desktop";
138216
}
217+
218+
return undefined;
219+
}
139220
}
140221

141222
const sML = new sMLFactory();
142223
const sMLWithRequest = new sMLFactoryWithRequest();
143-
export { sML, sMLWithRequest };
224+
export { sML, sMLWithRequest };

0 commit comments

Comments
 (0)