probably-china 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/index.js +94 -37
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
This is a simple package for the browser environment that makes a quick guess
|
|
7
7
|
to see if the current webpage is running in China, or if the user is from China,
|
|
8
|
-
based on the available browser info. It currently uses
|
|
9
|
-
|
|
10
|
-
1. Check if the current
|
|
11
|
-
2. Check if the current
|
|
8
|
+
based on the available browser info. It currently uses the following strategies:
|
|
9
|
+
|
|
10
|
+
1. Check if the current timezone is one of the Chinese timezones.
|
|
11
|
+
2. Check if the current browser favors simplified Chinese or related languages
|
|
12
|
+
(unless a Taiwanese language tag comes first).
|
|
13
|
+
3. Check if the user agent is an in-app browser or a browser that is mostly used in China
|
|
14
|
+
(such as WeChat, QQ, Alipay, Douyin, or HarmonyOS).
|
|
15
|
+
4. Check if the user comes from a Chinese website (such as Baidu or Zhihu).
|
|
12
16
|
|
|
13
17
|
The use case for this package is not to avoid showing information that are sensitive in China.
|
|
14
18
|
|
package/dist/index.js
CHANGED
|
@@ -1,37 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
const detectChinaRegion = ["cn", "hk", "mo"];
|
|
2
|
+
const detectChinaTimeZone = [
|
|
3
|
+
"Asia/Shanghai", "Asia/Urumqi", "Asia/Hong_Kong", "Asia/Macau",
|
|
4
|
+
// Legacy aliases, which may be returned as-is in some environments
|
|
5
|
+
"PRC", "Asia/Chongqing", "Asia/Chungking", "Asia/Harbin", "Asia/Kashgar", "Asia/Macao", "Hongkong",
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
// In-app browsers or browsers that are mostly used in China only.
|
|
9
|
+
// Browsers with a large user base outside China (such as UC, Mi, HeyTap, vivo or Huawei) are intentionally excluded.
|
|
10
|
+
const detectChinaUserAgent = new RegExp([
|
|
11
|
+
"MicroMessenger", "MQQBrowser", "QQ/", "Quark", "baiduboxapp", "BIDUBrowser", "AlipayClient", "DingTalk",
|
|
12
|
+
"Weibo", "aweme", "NewsArticle", "Feishu", "SogouMobileBrowser", "MetaSr", "360SE", "360EE",
|
|
13
|
+
"2345Explorer", "LBBROWSER", "OpenHarmony", "ArkWeb",
|
|
14
|
+
].join("|"));
|
|
15
|
+
|
|
16
|
+
const detectChinaReferrer = /^https?:\/\/([^/]+\.)?(baidu\.com|so\.com|sogou\.com|sm\.cn|cn\.bing\.com|weixin\.qq\.com|weixin110\.qq\.com|zhihu\.com|weibo\.com|weibo\.cn|xiaohongshu\.com|douyin\.com|bilibili\.com)(:\d+)?(\/|$)/i;
|
|
17
|
+
|
|
18
|
+
function checkTimeZone() {
|
|
19
|
+
if(typeof Intl !== "undefined") {
|
|
20
|
+
const timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
21
|
+
return detectChinaTimeZone.indexOf(timeZone) >= 0;
|
|
22
|
+
} else {
|
|
23
|
+
// legacy browser
|
|
24
|
+
const str = new Date().toString();
|
|
25
|
+
return str.indexOf("中") > 0 || str.indexOf("香") > 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Classify a language tag.
|
|
31
|
+
* @param {string} tag
|
|
32
|
+
* @returns {boolean | undefined} `true` for China, `false` for Taiwan, `undefined` if undecided.
|
|
33
|
+
*/
|
|
34
|
+
function classifyLanguage(tag) {
|
|
35
|
+
// Old browsers (such as Safari < 10) report tags in lower case.
|
|
36
|
+
const parts = tag.toLowerCase().split("-");
|
|
37
|
+
if(parts[0] !== "zh") return undefined;
|
|
38
|
+
|
|
39
|
+
// Legacy Microsoft tags
|
|
40
|
+
if(parts[1] === "chs") return true;
|
|
41
|
+
if(parts[1] === "cht") return false;
|
|
42
|
+
|
|
43
|
+
let script = "", region = "";
|
|
44
|
+
for(let i = 1; i < parts.length; i++) {
|
|
45
|
+
if(parts[i].length === 4) script = parts[i];
|
|
46
|
+
else if(parts[i].length === 2) region = parts[i];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Region takes precedence, so for example "zh-Hans-SG" is not China.
|
|
50
|
+
if(region === "tw") return false;
|
|
51
|
+
if(detectChinaRegion.indexOf(region) >= 0) return true;
|
|
52
|
+
if(region) return undefined;
|
|
53
|
+
|
|
54
|
+
// No region; "zh" and "zh-Hans" maximize to "zh-Hans-CN", while "zh-Hant" maximizes to "zh-Hant-TW".
|
|
55
|
+
if(script === "hant") return false;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function checkChinaLanguages() {
|
|
60
|
+
const list = [];
|
|
61
|
+
if(navigator.languages) { // https://caniuse.com/mdn-api_navigator_languages
|
|
62
|
+
for(let i = 0; i < navigator.languages.length; i++) list.push(navigator.languages[i]);
|
|
63
|
+
} else if(navigator.language) {
|
|
64
|
+
// legacy browser
|
|
65
|
+
list.push(navigator.language);
|
|
66
|
+
}
|
|
67
|
+
// The browser UI locale, which in some browsers (such as Firefox) can differ from the content language list.
|
|
68
|
+
if(typeof Intl !== "undefined") list.push(new Intl.DateTimeFormat().resolvedOptions().locale);
|
|
69
|
+
|
|
70
|
+
for(let i = 0; i < list.length; i++) {
|
|
71
|
+
// Some Taiwanese users might also have "zh-CN" in their language list.
|
|
72
|
+
// The first decisive tag wins, so that it returns false if "zh-TW" comes first in the language list.
|
|
73
|
+
const result = classifyLanguage(list[i]);
|
|
74
|
+
if(result !== undefined) return result;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function checkUserAgent() {
|
|
80
|
+
// False positive: navigator.userAgent exists in early Opera versions, but the compat data only records it since Opera 10.5.
|
|
81
|
+
// eslint-disable-next-line compat/compat
|
|
82
|
+
return detectChinaUserAgent.test(navigator.userAgent || "");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function checkReferrer() {
|
|
86
|
+
return typeof document !== "undefined" && detectChinaReferrer.test(document.referrer);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* A lucky guess that we are probably in China or facing a Chinese user.
|
|
91
|
+
*/
|
|
92
|
+
export const probablyChina = checkTimeZone() || checkChinaLanguages() || checkUserAgent() || checkReferrer();
|
|
93
|
+
|
|
94
|
+
export default probablyChina;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "probably-china",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "A lucky guess that we are probably in China or facing a Chinese user.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"China"
|
|
9
9
|
],
|
|
10
10
|
"author": "Mu-Tsun Tsai <don.m.t.tsai@gmail.com> (https://github.com/MuTsunTsai)",
|
|
11
|
-
"repository":
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "github:MuTsunTsai/probably-china"
|
|
14
|
+
},
|
|
12
15
|
"license": "MIT",
|
|
13
16
|
"files": [
|
|
14
17
|
"dist"
|