-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathbrowser-compatibility.js
More file actions
207 lines (200 loc) · 8.03 KB
/
browser-compatibility.js
File metadata and controls
207 lines (200 loc) · 8.03 KB
1
2
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
(()=>{
const features = [
{
name: "BigInt value (1n) / BigInt 数据类型(1n)",
version:{firefox:68,chrome:67,safari:14},
url: "https://caniuse.com/bigint",
test: ()=>Boolean(runCodeWithFunction("1n"))
},
{
name: "Optional chaining (?.) / 可选链操作符(?.)",
version:{firefox:74,chrome:80,safari:13.4},
url: "https://caniuse.com/mdn-javascript_operators_optional_chaining",
test: ()=>Boolean(runCodeWithFunction("undefined?.undefined || true"))
},
{
name: "Nullish coalescing operator (??) / 空值合并操作符(??)",
version:{firefox:72,chrome:80,safari:13.4},
url: "https://caniuse.com/mdn-javascript_operators_nullish_coalescing",
test: ()=>Boolean(runCodeWithFunction("undefined ?? true"))
},
{
name: "regular_expressions: Named capture group: (?<name>...) / 正则表达式: 命名捕获组",
version:{firefox:78,chrome:64,safari:11.1},
url: "https://caniuse.com/mdn-javascript_regular_expressions_named_capturing_group",
test: ()=>Boolean(runCodeWithFunction("/(?<name>)/"))
},
{
name: "CSS selector: :where() / CSS选择器: :where()",
version:{firefox:78,chrome:88,safari:14},
url: "https://caniuse.com/mdn-css_selectors_where",
test: ()=>supportsPseudoClass(":where()")
},
{
name: "CSS selector: :not() / CSS选择器: :not()",
version:{firefox:84,chrome:88,safari:9},
url: "https://caniuse.com/css-not-sel-list",
test: ()=>supportsPseudoClass(":not(html)")
},
// {
// name: "CSS selector: :has() / CSS选择器: :has()",
// version:{firefox:121,chrome:105,safari:15.4},
// url: "https://caniuse.com/css-has",
// test: ()=>supportsPseudoClass(":has(html)")
// },
{
name: "Private class fields (#name) / 类私有域(#name)",
version:{firefox:90,chrome:74,safari:14.5},
url: "https://caniuse.com/mdn-javascript_classes_private_class_fields",
test: ()=>Boolean(runCodeWithFunction("class test {#v = 0;}, true"))
},
{
name: "Dialog element / Dialog 元素",
version:{firefox:98,chrome:37,safari:15.4},
url: "https://caniuse.com/dialog",
test: ()=>Boolean(window.HTMLDialogElement)
},
// {
// name: "Class static initialization blocks / 静态初始化块",
// version:{firefox:93,chrome:94,safari:16.4},
// url: "https://caniuse.com/mdn-javascript_classes_static_initialization_blocks",
// test: ()=>Boolean(runCodeWithFunction("class test { static { this.staticProperty = true;};}, true"))
// },
{
name: "Array.prototype.toSorted()",
version:{firefox:115,chrome:110,safari:16.0},
url: "https://caniuse.com/mdn-javascript_builtins_array_tosorted",
test: ()=>Boolean(Array.prototype.toSorted)
},
{
name: "Set.prototype.isDisjointFrom()",
version:{firefox:127,chrome:122,safari:17.0},
url: "https://caniuse.com/mdn-javascript_builtins_set_isdisjointfrom",
test: ()=>Boolean(Set.prototype.isDisjointFrom)
},
// {
// name: "Duplicate named capture group / 重复的正则表达式匹配命名组",
// version:{firefox:129,chrome:125,safari:17.0},
// url: "https://caniuse.com/mdn-javascript_regular_expressions_named_capturing_group_duplicate_named_capturing_groups",
// test: ()=>Boolean(runCodeWithFunction("/(?<year>\\d{4})-\\d{2}|\\d{2}-(?<year>\\d{4})/"))
// },
{
name: "Uint8Array.fromBase64()",
version:{firefox:133,chrome:140,safari:18.2},
url: "https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64",
test: ()=>Boolean(Uint8Array.fromBase64)
},
{
name: "Uint8Array.prototype.toBase64()",
version:{firefox:133,chrome:140,safari:18.2},
url: "https://caniuse.com/mdn-javascript_builtins_uint8array_tobase64",
test: ()=>Boolean(Uint8Array.prototype.toBase64)
},
{ // 由于浏览器都有这个标识但未实现功能,所以这一项无法用此手段检测。
name: "CSS property: paint-order / CSS属性: paint-order",
version:{firefox:60,chrome:123,safari:11},
url: "https://caniuse.com/mdn-css_properties_paint-order",
test: () => CSS.supports('paint-order: stroke')
},
];
function runCodeWithFunction(obj) {
return Function(`"use strict"; return (${obj})`)();
}
function supportsPseudoClass(clazz) {
const style = document.createElement('style');
style.innerHTML = clazz + '{}';
document.head.appendChild(style); // required, or style.sheet === null
const result = style.sheet.cssRules.length === 1;
style.remove(); // document.head.removeChild(style);
return result;
}
const unsupportFeatures = features.filter(feature=>{
try {
return !feature.test();
} catch (e) {
if (e.name !== 'SyntaxError')
console.error(e);
return true;
}
});
if (unsupportFeatures.length) {
const browserVersion = ((UA)=>{
let regRes;
if (regRes = /\b(Firefox|Chrome)\/([\d\.]+)/ig.exec(UA)) {
return `${regRes[1]} ${regRes[2]}`;
} else if (regRes = /\bVersion\/([\d\.]+)\s+.*\b(Safari)\//ig.exec(UA)) {
return `${regRes[2]} ${regRes[1]}`;
} else {
return UA;
}
})(navigator.userAgent);
//支持的最低版本
const needBrowserVersion = unsupportFeatures.reduce((pre,{version})=>{
pre.firefox = Math.max(pre.firefox,version.firefox);
pre.chrome = Math.max(pre.chrome,version.chrome);
pre.safari = Math.max(pre.safari,version.safari);
return pre;
}, {firefox:0,chrome:0,safari:0});
let alertStr;
if (/^zh-(?:han(?:s|t)-)?/.test(navigator.language)) {
alertStr =
`<p lang="zh">🙁浏览器内核版本太老<br>
您的浏览器版本为: ${browserVersion}<br>
您的浏览器内核不支持本程序使用的以下技术
<ol>
${unsupportFeatures.map(feature=>`<li><a href="${feature.url}">${feature.name}</a></li>`).join('')}
</ol>
请更新您的浏览器内核到 Firefox(火狐) ≥ ${needBrowserVersion.firefox} 或 Chrome(谷歌) ≥ ${needBrowserVersion.chrome} 或 Safari ≥ ${needBrowserVersion.safari}。<br>
如果您使用的是已经停止支持的 Windows XP 或 Windows 7,可以使用 <a href="https://www.win32subsystem.live/supermium/">Supermium 浏览器</a> 以支持新特性。</p>`;
} else {
alertStr =
`<p lang="en">🙁Browser kernel is too old<br>
Your browser is: ${browserVersion}<br>
Your browser kernel does not support the following technologies used by this program:
<ol>
${unsupportFeatures.map(feature=>`<li><a href="${feature.url}">${feature.name}</a></li>`).join('')}
</ol>
Please update your browser core to Firefox ≥ ${needBrowserVersion.firefox} or Chrome ≥ ${needBrowserVersion.chrome} or Safari ≥ ${needBrowserVersion.safari}.<br>
If you are using Windows XP or Windows 7, which are no longer supported, you can use the <a href="https://www.win32subsystem.live/supermium/">Supermium browser</a> to gain support for modern web features.</p>`;
}
//alert(alertStr);
const event = window.addEventListener("load", ()=>{
document.body.insertAdjacentHTML("afterbegin", alertStr);
window.removeEventListener("load", event);
});
}
if (/\b(?:MicroMessenger|WeChat|Weixin|QQ|AliApp)\b/.test(navigator.userAgent)) {
const mask = document.createElement("div");
mask.id = "denied-mask";
const css = `
#denied-mask {
position: fixed;
height: 100%;
width: 100%;
top: 0;
left: 0;
background-color: #000A;
}
.alert {
font-size: 2em;
font-weight: bold;
color: white;
text-align: center;
}
`;
const style = mask.appendChild(document.createElement("style"));
style.appendChild(document.createTextNode(css));
const alertDiv = mask.appendChild(document.createElement("div"));
alertDiv.className = "alert";
alertDiv.innerHTML = `请勿使用APP内置浏览器,会有功能缺失<br>点击菜单使用正常浏览器打开↗`;
const removeMe = mask.appendChild(document.createElement("button"));
removeMe.append("我知道了");
removeMe.onclick = ()=>{
mask.remove();
};
const event = window.addEventListener("load", ()=>{
document.body.appendChild(mask);
window.removeEventListener("load", event);
});
}
})();