更新检测脚本

master
yutent 2023-07-18 23:54:00 +08:00
parent 416c9aed37
commit 549718fac8
8 changed files with 161 additions and 57 deletions

File diff suppressed because one or more lines are too long

BIN
public/appfont.ttf Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -43,7 +43,7 @@
.info { .info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 212px; width: 256px;
padding: 8px 12px; padding: 8px 12px;
background: var(--color-plain-1); background: var(--color-plain-1);

View File

@ -4,8 +4,15 @@
* @date 2023/07/18 19:11:01 * @date 2023/07/18 19:11:01
*/ */
import { IS_SAFARI } from './env.js'
// 用canvas检测图形/图象的支持 // 用canvas检测图形/图象的支持
export function checkCanvas(type) { export function checkCanvas(type) {
// macos下的safari, 调用webgpu,会崩溃
// 所以, webgpu不能用canvas调用来判断
if (type == 'webgpu') {
return !!navigator.gpu ^ 0
}
try { try {
var canvas = document.createElement('canvas') var canvas = document.createElement('canvas')
var ctx = canvas.getContext(type) var ctx = canvas.getContext(type)
@ -16,10 +23,9 @@ export function checkCanvas(type) {
} }
} }
export function checkMedia(type, isAudio = true) { export function checkMedia(type, isAudio = 1) {
let ctx = isAudio ? new Audio() : document.createElement('video') let ctx = isAudio ? new Audio() : document.createElement('video')
let res = ctx.canPlayType(type) let res = ctx.canPlayType(type)
console.log(isAudio, res)
if (res === 'maybe' || res === 'probably') { if (res === 'maybe' || res === 'probably') {
return 1 return 1
} }

View File

@ -4,18 +4,23 @@
* @date 2023/07/18 16:16:02 * @date 2023/07/18 16:16:02
*/ */
const UA = navigator.userAgent.toLowerCase() const UNKNOW = 'Unknow'
const UNKNOW_MATCH = [null, 'unknow']
const IS_CHROME = !!window.chrome export const UA = navigator.userAgent.toLowerCase()
const IS_FIREFOX = !!window.sidebar export const UNKNOW_MATCH = [null, UNKNOW]
const IS_LINUX = UA.includes('linux') /* 分辨率 */
const IS_WIN = UA.includes('windows nt') const SCREEN = `${screen.width} x ${screen.height}`
const IS_ANDROID = UA.includes('android')
const IS_IOS = /* 操作系统 */
export const IS_LINUX = UA.includes('linux')
export const IS_WIN = UA.includes('windows nt')
export const IS_MACOS = UA.includes('mac os x')
export const IS_ANDROID = UA.includes('android')
export const IS_IOS =
UA.includes('iphone') || UA.includes('ipad') || UA.includes('ipod') UA.includes('iphone') || UA.includes('ipad') || UA.includes('ipod')
const IS_MOBILE = IS_ANDROID || IS_IOS || UA.includes('mobile') export const IS_MOBILE = IS_ANDROID || IS_IOS || UA.includes('mobile')
const OS_NAME = IS_ANDROID const OS_NAME = IS_ANDROID
? 'Android' ? 'Android'
@ -25,12 +30,18 @@ const OS_NAME = IS_ANDROID
? 'Linux' ? 'Linux'
: IS_WIN : IS_WIN
? 'Windows' ? 'Windows'
: 'MacOS' : IS_MACOS
? 'MacOS'
: UNKNOW
const OS_VERSION = IS_ANDROID ? UA.match(/android ([\d\.]*?);/)[1] : '' const OS_VERSION = IS_ANDROID ? UA.match(/android ([\d\.]*?);/)[1] : ''
const SCREEN = `${screen.width} x ${screen.height}` /* 浏览器 */
export const IS_CHROME = !!window.chrome
export const IS_FIREFOX = 'MozAppearance' in document.documentElement.style
export const IS_SAFARI = (IS_MACOS || IS_IOS) && !!window.safari
const BROWSER_NAME = IS_IOS /* 浏览器名称 */
const BROWSER_NAME = IS_SAFARI
? 'Safari' ? 'Safari'
: IS_CHROME : IS_CHROME
? 'Chrome' ? 'Chrome'
@ -38,16 +49,25 @@ const BROWSER_NAME = IS_IOS
? 'Firefox' ? 'Firefox'
: 'Unknow' : 'Unknow'
/* 浏览器版本 */
const GENERAL_VERSION = UA.match(/version\/([\d\.]*?) /) || UNKNOW_MATCH const GENERAL_VERSION = UA.match(/version\/([\d\.]*?) /) || UNKNOW_MATCH
const CHROME_VERSION = const CHROME_VERSION = UA.match(/chrome\/([\d\.]*?) /) || UNKNOW_MATCH
IS_CHROME && (UA.match(/chrome\/([\d\.]*?) /) || UNKNOW_MATCH) const IPAD_WEBKIT_VERSION = UA.match(/crios\/([\d\.]*?) /) || GENERAL_VERSION
const IPAD_WEBKIT_VERSION = const FIREFOX_VERSION = UA.match(/firefox\/([\d\.]*)/) || UNKNOW_MATCH
IS_IOS && (UA.match(/crios\/([\d\.]*?) /) || GENERAL_VERSION)
const BROWSER_VERSION = IS_IOS const BROWSER_VERSION = IS_IOS
? IPAD_WEBKIT_VERSION[1] ? IPAD_WEBKIT_VERSION[1]
: IS_CHROME : IS_CHROME
? CHROME_VERSION[1] ? CHROME_VERSION[1]
: IS_FIREFOX
? FIREFOX_VERSION[1]
: GENERAL_VERSION[1] : GENERAL_VERSION[1]
// 是否支持 Import assertions
export const SUPPORT_ASSERTIONS = IS_CHROME
? CHROME_VERSION[1].split('.').shift() > 91
: IS_SAFARI
? GENERAL_VERSION[1].split('.').shift() >= 15
: false
export { OS_NAME, OS_VERSION, BROWSER_NAME, BROWSER_VERSION, SCREEN } export { OS_NAME, OS_VERSION, BROWSER_NAME, BROWSER_VERSION, SCREEN }

View File

@ -12,7 +12,7 @@ const store = reactive({
{ {
name: '音频支持', name: '音频支持',
total: 0, total: 0,
factor: 80, factor: 70,
scores: [ scores: [
!!window.AudioContext ^ 0, !!window.AudioContext ^ 0,
checkMedia('audio/wav'), checkMedia('audio/wav'),
@ -29,19 +29,17 @@ const store = reactive({
'flac support', 'flac support',
'aac support', 'aac support',
'ogg support', 'ogg support',
'webm support', 'webm support'
'Dolby Digital support',
'Dolby Digital Plus support'
] ]
}, },
{ {
name: '视频支持', name: '视频支持',
total: 0, total: 0,
factor: 80, factor: 70,
scores: [ scores: [
checkMedia('video/mp4; codecs="mp4v.20.8"', 0), checkMedia('video/mp4; codecs="mp4v.20.8"', 0),
checkMedia('video/mp4', 0), checkMedia('video/mp4', 0),
checkMedia('video/mp4; codecs="hev1"', 0), checkMedia('video/mp4; codecs="hev1"', 0) * 1.1,
checkMedia('video/ogg', 0), checkMedia('video/ogg', 0),
checkMedia('video/webm; codecs="vp8"', 0), checkMedia('video/webm; codecs="vp8"', 0),
checkMedia('video/webm; codecs="vp9"', 0) checkMedia('video/webm; codecs="vp9"', 0)
@ -58,7 +56,20 @@ const store = reactive({
{ {
name: '流媒体', name: '流媒体',
total: 0, total: 0,
scores: [1, 1, 0, 0], scores: [
1,
!!navigator.requestMediaKeySystemAccess ^ 0,
MediaSource.isTypeSupported(
'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
)
? 1.1
: 0,
MediaSource.isTypeSupported(
'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
)
? 1.1
: 0
],
factor: 100, factor: 100,
items: [ items: [
'Media Source extensions', 'Media Source extensions',
@ -67,30 +78,6 @@ const store = reactive({
'HTTP Live Streaming / HLS' 'HTTP Live Streaming / HLS'
] ]
}, },
{
name: '自定义组件',
total: 0,
factor: 80,
scores: [
!!window.customElements ^ 0,
!!document.body.attachShadow ^ 0,
!!document.adoptedStyleSheets ^ 0
],
items: ['Custom elements', 'Shadow DOM', 'adoptedStyleSheets']
},
{
name: '图形图象支持',
total: 0,
factor: 120,
scores: [
checkCanvas('2d'),
checkCanvas('webgl'),
checkCanvas('webgl2'),
checkCanvas('webgpu'),
!!navigator.xr ^ 0
],
items: ['canvas 2D', 'WebGL', 'WebGL 2', 'WebGPU', 'WebVR']
},
{ {
name: '网络', name: '网络',
total: 0, total: 0,
@ -107,11 +94,106 @@ const store = reactive({
'fetch api', 'fetch api',
'ArrayBuffer and Blob support' 'ArrayBuffer and Blob support'
] ]
},
{
name: '数据流',
factor: 80,
total: 0,
scores: [
!!window.FileSystemHandle ^ 0,
!!window.ReadableStream ^ 0,
!!window.WritableStream ^ 0
],
items: ['File System', 'Readable Stream', 'Writable Stream']
},
{
name: '自定义组件',
total: 0,
factor: 80,
scores: [
!!window.customElements ^ 0,
!!document.body.attachShadow ^ 0,
document.adoptedStyleSheets ? 1.1 : 0
],
items: ['Custom elements', 'Shadow DOM', 'adoptedStyleSheets']
},
{
name: '图形图象支持',
total: 0,
factor: 120,
scores: [
checkCanvas('2d'),
checkCanvas('webgl'),
checkCanvas('webgl2') * 1.1,
checkCanvas('webgpu') * 2,
navigator.xr ? 2 : 0
],
items: ['canvas 2D', 'WebGL', 'WebGL 2', 'WebGPU', 'WebVR']
},
{
name: '点对点连接',
total: 0,
factor: 40,
scores: [
!!(
window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection
) ^ 0,
window.RTCIceTransport ||
window.webkitRTCIceTransport ||
window.mozRTCIceTransport
? 2.5
: 0,
!!navigator.getUserMedia ^ 0,
navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia
? 1.5
: 0,
!!window.MediaRecorder ^ 0
],
items: [
'WebRTC 1.0',
'ObjectRTC API for WebRTC',
'Access the webcam',
'Screen Capture',
'Media Stream recorder'
]
},
{
name: 'ES6模块',
total: 0,
factor: 40,
scores: [1, env.SUPPORT_ASSERTIONS ? 2.5 : 0],
items: ['import/export', 'Import assertions']
},
{
name: '性能',
total: 0,
factor: 70,
scores: [!!navigator.serviceWorker ^ 0, window.WebAssembly ? 1.5 : 0],
items: ['Web Workers', 'WebAssembly']
},
{
name: '其他',
total: 0,
factor: 80,
scores: [
!!navigator.bluetooth ^ 0,
navigator.clipboard ? 0.8 : 0,
navigator.usb ? 2 : 0,
!!navigator.windowControlsOverlay ^ 0
],
items: ['Bluetooth', 'clipboard', 'USB', 'Window Controls Overlay']
} }
] ]
}) })
store.modules.forEach(it => (it.total = it.items.length)) store.modules.forEach(
it => (
(it.total = it.items.length),
(it.passed = it.scores.filter(n => n > 0).length)
)
)
store.scores = store.modules.map(it => it.scores.sum() * it.factor).sum() store.scores = store.modules.map(it => it.scores.sum() * it.factor).sum()
export default function (app) { export default function (app) {

View File

@ -4,7 +4,7 @@
<wc-card v-for="it in $store.modules"> <wc-card v-for="it in $store.modules">
<wc-space justify class="mod-header" slot="header"> <wc-space justify class="mod-header" slot="header">
{{ it.name }} {{ it.name }}
<span class="scores">{{ it.scores.sum() }}/{{ it.total }}</span> <span class="scores">{{ it.passed }}/{{ it.total }}</span>
</wc-space> </wc-space>
<div class="body"> <div class="body">