diff --git a/package.json b/package.json index 92401e5dc3b20dba7751f6fdd61f2afe89bb4f12..f22aadf060ed74887f16e7812f3b1cd922e876f8 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "devDependencies": { "@babel/core": "^7.17.10", "@babel/preset-env": "^7.16.11", - "@dcloudio/types": "^2.6.6", + "@dcloudio/types": "^2.6.8", "@dcloudio/uni-api": "3.0.0-alpha-3041020220516004", "@dcloudio/uni-app": "3.0.0-alpha-3041020220516004", "@jest/types": "^27.0.2", diff --git a/packages/uni-app-plus/src/service/api/device/getWindowInfo.ts b/packages/uni-app-plus/src/service/api/device/getWindowInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..3a6ab39b1f59bdcd824cfbb39cb72c9344345405 --- /dev/null +++ b/packages/uni-app-plus/src/service/api/device/getWindowInfo.ts @@ -0,0 +1,110 @@ +import { NAVBAR_HEIGHT } from '@dcloudio/uni-shared' +import tabBar from '../../framework/app/tabBar' +import { getCurrentWebview } from '../../utils' +import { getStatusbarHeight } from '../../../helpers/statusBar' +import { isTabBarPage } from '../../../helpers/plus' +import { defineSyncApi } from '@dcloudio/uni-api' + +type SafeAreaInsets = Required + +function getScreenInfo() { + // 好像开发时刷新,偶发的 plus.screen.getCurrentSize 为 undefined + const { resolutionWidth, resolutionHeight } = + plus.screen.getCurrentSize() || { + resolutionWidth: 0, + resolutionHeight: 0, + } + return { + screenWidth: Math.round(resolutionWidth), + screenHeight: Math.round(resolutionHeight), + } +} + +export const getWindowInfo = defineSyncApi( + 'getWindowInfo', + () => { + const ios = plus.os.name!.toLowerCase() === 'ios' + + const { screenWidth, screenHeight } = getScreenInfo() + const statusBarHeight = getStatusbarHeight() + + let safeAreaInsets: SafeAreaInsets + const titleNView = { + height: 0, + cover: false, + } + const webview = getCurrentWebview() + if (webview) { + const webStyle = webview.getStyle() + const style = webStyle && webStyle.titleNView + if (style && style.type && (style as any).type !== 'none') { + titleNView.height = + style.type === 'transparent' ? 0 : statusBarHeight + NAVBAR_HEIGHT + titleNView.cover = + style.type === 'transparent' || style.type === 'float' + } + safeAreaInsets = webview.getSafeAreaInsets() as SafeAreaInsets + } else { + safeAreaInsets = plus.navigator.getSafeAreaInsets() as SafeAreaInsets + } + const tabBarView = { + height: 0, + cover: false, + } + if (isTabBarPage()) { + tabBarView.height = tabBar.visible ? tabBar.height : 0 + tabBarView.cover = tabBar.cover + } + const windowTop = titleNView.cover ? titleNView.height : 0 + const windowBottom = tabBarView.cover ? tabBarView.height : 0 + let windowHeight = screenHeight - titleNView.height - tabBarView.height + let windowHeightReal = + screenHeight - + (titleNView.cover ? 0 : titleNView.height) - + (tabBarView.cover ? 0 : tabBarView.height) + const windowWidth = screenWidth + if ( + (!tabBarView.height || tabBarView.cover) && + !safeAreaInsets.bottom && + safeAreaInsets.deviceBottom + ) { + windowHeight -= safeAreaInsets.deviceBottom + windowHeightReal -= safeAreaInsets.deviceBottom + } + safeAreaInsets = ios + ? safeAreaInsets + : ({ + left: 0, + right: 0, + top: titleNView.height && !titleNView.cover ? 0 : statusBarHeight, + bottom: 0, + } as SafeAreaInsets) + const safeArea = { + left: safeAreaInsets.left, + right: windowWidth - safeAreaInsets.right, + top: safeAreaInsets.top, + bottom: windowHeightReal - safeAreaInsets.bottom, + width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, + height: windowHeightReal - safeAreaInsets.top - safeAreaInsets.bottom, + } + + return { + pixelRatio: plus.screen.scale!, + screenWidth, + screenHeight, + windowWidth, + windowHeight, + statusBarHeight, + safeArea, + safeAreaInsets: { + top: safeAreaInsets.top, + right: safeAreaInsets.right, + bottom: safeAreaInsets.bottom, + left: safeAreaInsets.left, + }, + windowTop, + windowBottom, + screenTop: screenHeight - windowHeight, + } + } +) diff --git a/packages/uni-app-plus/src/service/api/device/systemInfo.ts b/packages/uni-app-plus/src/service/api/device/systemInfo.ts index d84b82af24ec154a809cff2181bc5ccfa50e9e32..f37d504dd129b519573eeadf404925330ea8ddc6 100644 --- a/packages/uni-app-plus/src/service/api/device/systemInfo.ts +++ b/packages/uni-app-plus/src/service/api/device/systemInfo.ts @@ -1,132 +1,122 @@ -import { NAVBAR_HEIGHT } from '@dcloudio/uni-shared' import { defineAsyncApi, defineSyncApi } from '@dcloudio/uni-api' -import tabBar from '../../framework/app/tabBar' -import { getCurrentWebview } from '../../utils' -import { getStatusbarHeight } from '../../../helpers/statusBar' -import { isTabBarPage } from '../../../helpers/plus' import deviceId from '../../../helpers/uuid' import { extend } from '@vue/shared' +import { getWindowInfo } from './getWindowInfo' -type SafeAreaInsets = Required +let systemInfo: any +let _initSystemInfo = true -function getScreenInfo() { - // 好像开发时刷新,偶发的 plus.screen.getCurrentSize 为 undefined - const { resolutionWidth, resolutionHeight } = - plus.screen.getCurrentSize() || { - resolutionWidth: 0, - resolutionHeight: 0, +function weexGetSystemInfoSync() { + if (!_initSystemInfo) return + const { getSystemInfoSync } = weex.requireModule('plus') + systemInfo = getSystemInfoSync() +} + +export const getDeviceInfo = defineSyncApi( + 'getDeviceInfo', + () => { + weexGetSystemInfoSync() + const { deviceBrand, deviceModel, osName, osVersion } = systemInfo + + const brand = deviceBrand.toLowerCase() + + return { + deviceBrand: brand, + deviceModel, + brand, + model: deviceModel, + system: `${osName === 'ios' ? 'iOS' : 'Android'} ${osVersion}`, + platform: osName, } - return { - screenWidth: Math.round(resolutionWidth), - screenHeight: Math.round(resolutionHeight), } -} +) + +export const getAppBaseInfo = defineSyncApi( + 'getAppBaseInfo', + () => { + weexGetSystemInfoSync() + const { + hostPackageName, + hostName, + osLanguage, + hostVersion, + hostLanguage, + hostTheme, + appId, + appName, + appVersion, + appVersionCode, + } = systemInfo + + return { + SDKVersion: '', + hostSDKVersion: '', + enableDebug: false, + appId, + appName, + appVersion, + appVersionCode, + appLanguage: uni.getLocale(), + version: plus.runtime.innerVersion!, + language: osLanguage, + theme: '', + hostPackageName, + hostName, + hostVersion, + hostLanguage, + hostTheme, + hostFontSizeSetting: undefined, + } + } +) export const getSystemInfoSync = defineSyncApi( 'getSystemInfoSync', () => { - const { getSystemInfoSync } = weex.requireModule('plus') - const info = getSystemInfoSync() - const { deviceBrand, deviceModel, osName, osVersion, osLanguage } = info - const brand = deviceBrand.toLowerCase() - const _osName = osName.toLowerCase() - const ios = _osName === 'ios' + _initSystemInfo = true + weexGetSystemInfoSync() + _initSystemInfo = false + const windowInfo = getWindowInfo() + const deviceInfo = getDeviceInfo() + const appBaseInfo = getAppBaseInfo() + _initSystemInfo = true - const { screenWidth, screenHeight } = getScreenInfo() - const statusBarHeight = getStatusbarHeight() + const { osName, osLanguage, osVersion } = systemInfo + const { pixelRatio } = windowInfo + const osLanguageSplit = osLanguage.split('-') + const osLanguageSplitLast = osLanguageSplit[osLanguageSplit.length - 1] + let _osLanguage = `${osLanguageSplit[0]}${ + osLanguageSplitLast ? '-' + osLanguageSplitLast : '' + }` - let safeAreaInsets: SafeAreaInsets - const titleNView = { - height: 0, - cover: false, - } - const webview = getCurrentWebview() - if (webview) { - const webStyle = webview.getStyle() - const style = webStyle && webStyle.titleNView - if (style && style.type && (style as any).type !== 'none') { - titleNView.height = - style.type === 'transparent' ? 0 : statusBarHeight + NAVBAR_HEIGHT - titleNView.cover = - style.type === 'transparent' || style.type === 'float' - } - safeAreaInsets = webview.getSafeAreaInsets() as SafeAreaInsets - } else { - safeAreaInsets = plus.navigator.getSafeAreaInsets() as SafeAreaInsets - } - const tabBarView = { - height: 0, - cover: false, + let extraData = { + errMsg: 'getSystemInfo:ok', + fontSizeSetting: appBaseInfo.hostFontSizeSetting, + devicePixelRatio: pixelRatio, + deviceId: deviceId(), + uniCompileVersion: __uniConfig.compilerVersion, + uniRuntimeVersion: __uniConfig.compilerVersion, + osLanguage: _osLanguage, } - if (isTabBarPage()) { - tabBarView.height = tabBar.visible ? tabBar.height : 0 - tabBarView.cover = tabBar.cover - } - const windowTop = titleNView.cover ? titleNView.height : 0 - const windowBottom = tabBarView.cover ? tabBarView.height : 0 - let windowHeight = screenHeight - titleNView.height - tabBarView.height - let windowHeightReal = - screenHeight - - (titleNView.cover ? 0 : titleNView.height) - - (tabBarView.cover ? 0 : tabBarView.height) - const windowWidth = screenWidth - if ( - (!tabBarView.height || tabBarView.cover) && - !safeAreaInsets.bottom && - safeAreaInsets.deviceBottom - ) { - windowHeight -= safeAreaInsets.deviceBottom - windowHeightReal -= safeAreaInsets.deviceBottom - } - safeAreaInsets = ios - ? safeAreaInsets - : ({ - left: 0, - right: 0, - top: titleNView.height && !titleNView.cover ? 0 : statusBarHeight, - bottom: 0, - } as SafeAreaInsets) - const safeArea = { - left: safeAreaInsets.left, - right: windowWidth - safeAreaInsets.right, - top: safeAreaInsets.top, - bottom: windowHeightReal - safeAreaInsets.bottom, - width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, - height: windowHeightReal - safeAreaInsets.top - safeAreaInsets.bottom, + + if (osName === 'ios') { + ;(extraData as any).romName = osName + ;(extraData as any).romVersion = osVersion } - return extend( - { - brand: brand, - model: deviceModel, - pixelRatio: plus.screen.scale!, - screenWidth, - screenHeight, - windowWidth, - windowHeight, - statusBarHeight, - language: osLanguage, - system: `${osName} ${osVersion}`, - version: plus.runtime.innerVersion!, - platform: _osName, - SDKVersion: '', - windowTop, - windowBottom, - safeArea, - safeAreaInsets: { - top: safeAreaInsets.top, - right: safeAreaInsets.right, - bottom: safeAreaInsets.bottom, - left: safeAreaInsets.left, - }, - deviceId: deviceId(), - }, - info, - { - deviceBrand: brand, - osName: _osName, - } + const _systemInfo: UniApp.GetSystemInfoResult = extend( + windowInfo, + systemInfo, + deviceInfo, + appBaseInfo, + extraData ) + + delete (_systemInfo as any).screenTop + delete (_systemInfo as any).enableDebug + delete (_systemInfo as any).theme + + return _systemInfo } ) diff --git a/packages/uni-app-plus/src/service/api/index.ts b/packages/uni-app-plus/src/service/api/index.ts index 082b82d15f20c142f0f4a43ba5cff3eaf087f6ba..64c6f30584731021fb70a93dc080821901d6bc1d 100644 --- a/packages/uni-app-plus/src/service/api/index.ts +++ b/packages/uni-app-plus/src/service/api/index.ts @@ -23,6 +23,7 @@ export * from './device/soterAuthentication' export * from './device/scanCode' export * from './device/theme' export * from './device/brightness' +export * from './device/getWindowInfo' export * from './media/getImageInfo' export * from './media/getVideoInfo' diff --git a/packages/uni-h5-vite/lib/api.json b/packages/uni-h5-vite/lib/api.json index 144328b553a64b6aea931d238985d54d6eb426ff..a303ff2855a39e09d3ff57f48bcfe65657f6f33b 100644 --- a/packages/uni-h5-vite/lib/api.json +++ b/packages/uni-h5-vite/lib/api.json @@ -32,7 +32,9 @@ "createSelectorQuery", "createVideoContext", "downloadFile", + "getAppBaseInfo", "getClipboardData", + "getDeviceInfo", "getEnterOptionsSync", "getFileInfo", "getImageInfo", @@ -58,6 +60,7 @@ "getSystemInfoSync", "getTopWindowStyle", "getVideoInfo", + "getWindowInfo", "hideKeyboard", "hideLeftWindow", "hideLoading", diff --git a/packages/uni-h5/src/service/api/base/getBrowserInfo.ts b/packages/uni-h5/src/service/api/base/getBrowserInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..71833fdf4a0bdf36f65df8d49537c83adfacaa28 --- /dev/null +++ b/packages/uni-h5/src/service/api/base/getBrowserInfo.ts @@ -0,0 +1,228 @@ +import { + ua, + isIOS, + isAndroid, + isWindows, + isMac, + isLinux, + isIPadOS, +} from '../base/getBaseSystemInfo' + +function IEVersion() { + const userAgent = navigator.userAgent + const isIE = + userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 + const isEdge = userAgent.indexOf('Edge') > -1 && !isIE + const isIE11 = + userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1 + if (isIE) { + const reIE = new RegExp('MSIE (\\d+\\.\\d+);') + reIE.test(userAgent) + const fIEVersion = parseFloat(RegExp.$1) + if (fIEVersion > 6) { + return fIEVersion + } else { + return 6 + } + } else if (isEdge) { + return -1 + } else if (isIE11) { + return 11 + } else { + return -1 + } +} + +function getDeviceBrand(model: string) { + if (/iphone/gi.test(model) || /ipad/gi.test(model) || /mac/gi.test(model)) { + return 'apple' + } + if (/windows/gi.test(model)) { + return 'microsoft' + } +} + +export function getBrowserInfo() { + let osname + let osversion = '0' + let model = '' + let deviceType = 'phone' + const language = navigator.language + + if (isIOS) { + osname = 'iOS' + const osversionFind = ua.match(/OS\s([\w_]+)\slike/) + if (osversionFind) { + osversion = osversionFind[1].replace(/_/g, '.') + } + const modelFind = ua.match(/\(([a-zA-Z]+);/) + if (modelFind) { + model = modelFind[1] + } + } else if (isAndroid) { + osname = 'Android' + // eslint-disable-next-line no-useless-escape + const osversionFind = ua.match(/Android[\s/]([\w\.]+)[;\s]/) + if (osversionFind) { + osversion = osversionFind[1] + } + const infoFind = ua.match(/\((.+?)\)/) + const infos = infoFind ? infoFind[1].split(';') : ua.split(' ') + // eslint-disable-next-line no-useless-escape + const otherInfo = [ + /\bAndroid\b/i, + /\bLinux\b/i, + /\bU\b/i, + /^\s?[a-z][a-z]$/i, + /^\s?[a-z][a-z]-[a-z][a-z]$/i, + /\bwv\b/i, + /\/[\d\.,]+$/, + /^\s?[\d\.,]+$/, + /\bBrowser\b/i, + /\bMobile\b/i, + ] + for (let i = 0; i < infos.length; i++) { + const info = infos[i] + if (info.indexOf('Build') > 0) { + model = info.split('Build')[0].trim() + break + } + let other + for (let o = 0; o < otherInfo.length; o++) { + if (otherInfo[o].test(info)) { + other = true + break + } + } + if (!other) { + model = info.trim() + break + } + } + } else if (isIPadOS) { + model = 'iPad' + osname = 'iOS' + deviceType = 'pad' + osversion = typeof window.BigInt === 'function' ? '14.0' : '13.0' + } else if (isWindows || isMac || isLinux) { + model = 'PC' + osname = 'PC' + deviceType = 'pc' + osversion = '0' + + let osversionFind = ua.match(/\((.+?)\)/)![1] + + if (isWindows) { + osname = 'Windows' + switch (isWindows[1]) { + case '5.1': + osversion = 'XP' + break + case '6.0': + osversion = 'Vista' + break + case '6.1': + osversion = '7' + break + case '6.2': + osversion = '8' + break + case '6.3': + osversion = '8.1' + break + case '10.0': + osversion = '10' + break + } + + const framework = osversionFind && osversionFind.match(/[Win|WOW]([\d]+)/) + if (framework) { + osversion += ` x${framework[1]}` + } + } else if (isMac) { + osname = 'Mac' + const _osversion = + (osversionFind && osversionFind.match(/Mac OS X (.+)/)) || '' + + if (osversion) { + osversion = _osversion[1].replace(/_/g, '.') + // '10_15_7' or '10.16; rv:86.0' + if (osversion.indexOf(';') !== -1) { + osversion = osversion.split(';')[0] + } + } + } else if (isLinux) { + osname = 'Linux' + const _osversion = + (osversionFind && osversionFind.match(/Linux (.*)/)) || '' + + if (_osversion) { + osversion = _osversion[1] + // 'x86_64' or 'x86_64; rv:79.0' + if (osversion.indexOf(';') !== -1) { + osversion = osversion.split(';')[0] + } + } + } + } else { + osname = 'Other' + osversion = '0' + deviceType = 'other' + } + + const system = `${osname} ${osversion}` + const platform = osname.toLocaleLowerCase() + + let browserName = '' + let browseVersion = String(IEVersion()) + if (browseVersion !== '-1') { + browserName = 'IE' + } else { + const browseVendors = ['Version', 'Firefox', 'Chrome', 'Edge{0,1}'] + const vendors = ['Safari', 'Firefox', 'Chrome', 'Edge'] + for (let index = 0; index < browseVendors.length; index++) { + const vendor = browseVendors[index] + const reg = new RegExp(`(${vendor})/(\\S*)\\b`) + if (reg.test(ua)) { + browserName = vendors[index] + browseVersion = ua.match(reg)![2] + } + } + } + + // deviceBrand + let deviceBrand = '' + if (model) { + const _model = model.toLocaleLowerCase() + deviceBrand = + getDeviceBrand(_model) || + getDeviceBrand(osname.toLocaleLowerCase()) || + _model.split(' ')[0] + } + + // deviceOrientation + let deviceOrientation: 'portrait' | 'landscape' = 'portrait' + const orientation = + typeof window.screen.orientation === 'undefined' + ? window.orientation + : window.screen.orientation.angle + deviceOrientation = Math.abs(orientation) === 90 ? 'landscape' : 'portrait' + + return { + deviceBrand, + deviceModel: model, + deviceOrientation, + brand: deviceBrand, + model, + system, + platform, + browserName: browserName.toLocaleLowerCase(), + browseVersion, + language, + deviceType, + ua, + osname, + osversion, + theme: '', + } +} diff --git a/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts b/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts index b3d9e0348eec41955e6f860d6ef47413f1327597..46ae9655440cba2d892ceaccad58c23d75499c2a 100644 --- a/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts +++ b/packages/uni-h5/src/service/api/device/getSystemInfoSync.ts @@ -1,59 +1,60 @@ -import safeAreaInsets from 'safe-area-insets' - import { defineSyncApi } from '@dcloudio/uni-api' +import deviceId from '../../../helpers/uuid' +import { getBrowserInfo } from '../base/getBrowserInfo' +import { getWindowInfo } from './getWindowInfo' +import { extend } from '@vue/shared' -import { getWindowOffset } from '@dcloudio/uni-core' - -import { - ua, - isIOS, - isAndroid, - isWindows, - isMac, - isLinux, - isIPadOS, - isLandscape, - getScreenFix, - getScreenWidth, - getWindowWidth, - getScreenHeight, -} from '../base/getBaseSystemInfo' +let browserInfo: ReturnType +let _initBrowserInfo = true -import deviceId from '../../../helpers/uuid' +function initBrowserInfo() { + if (!_initBrowserInfo) return + browserInfo = getBrowserInfo() +} +export const getDeviceInfo = defineSyncApi( + 'getDeviceInfo', + () => { + initBrowserInfo() + const { deviceBrand, deviceModel, brand, model, platform, system } = + browserInfo -function IEVersion() { - const userAgent = navigator.userAgent - const isIE = - userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 - const isEdge = userAgent.indexOf('Edge') > -1 && !isIE - const isIE11 = - userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1 - if (isIE) { - const reIE = new RegExp('MSIE (\\d+\\.\\d+);') - reIE.test(userAgent) - const fIEVersion = parseFloat(RegExp.$1) - if (fIEVersion > 6) { - return fIEVersion - } else { - return 6 + return { + deviceBrand, + deviceModel, + brand, + model, + system, + platform, } - } else if (isEdge) { - return -1 - } else if (isIE11) { - return 11 - } else { - return -1 } -} +) +export const getAppBaseInfo = defineSyncApi( + 'getAppBaseInfo', + () => { + initBrowserInfo() + const { theme, browserName, browseVersion, language } = browserInfo -function getDeviceBrand(model: string) { - if (/iphone/gi.test(model) || /ipad/gi.test(model) || /mac/gi.test(model)) { - return 'apple' - } - if (/windows/gi.test(model)) { - return 'microsoft' + return { + SDKVersion: '', + hostSDKVersion: '', + enableDebug: false, + hostPackageName: '', + hostFontSizeSetting: undefined, + language, + hostName: browserName, + hostVersion: browseVersion, + hostTheme: theme, + hostLanguage: language, + theme, + appId: __uniConfig.appId, + appName: __uniConfig.appName, + appVersion: __uniConfig.appVersion, + appVersionCode: __uniConfig.appVersionCode, + appLanguage: uni.getLocale(), + version: __uniConfig.appVersion, + } } -} +) /** * 获取系统信息-同步 @@ -68,229 +69,53 @@ export const getSystemInfoSync = defineSyncApi( platform: 'nodejs', } as unknown as UniApp.GetSystemInfoResult } - const pixelRatio = window.devicePixelRatio - // 横屏时 iOS 获取的屏幕宽高颠倒,进行纠正 - const screenFix = getScreenFix() - const landscape = isLandscape(screenFix) - const screenWidth = getScreenWidth(screenFix, landscape) - const screenHeight = getScreenHeight(screenFix, landscape) - const windowWidth = getWindowWidth(screenWidth) - let windowHeight = window.innerHeight - const language = navigator.language - const statusBarHeight = safeAreaInsets.top - let osname - let osversion - let model = '' - let deviceType = 'phone' - - if (isIOS) { - osname = 'iOS' - const osversionFind = ua.match(/OS\s([\w_]+)\slike/) - if (osversionFind) { - osversion = osversionFind[1].replace(/_/g, '.') - } - const modelFind = ua.match(/\(([a-zA-Z]+);/) - if (modelFind) { - model = modelFind[1] - } - } else if (isAndroid) { - osname = 'Android' - // eslint-disable-next-line no-useless-escape - const osversionFind = ua.match(/Android[\s/]([\w\.]+)[;\s]/) - if (osversionFind) { - osversion = osversionFind[1] - } - const infoFind = ua.match(/\((.+?)\)/) - const infos = infoFind ? infoFind[1].split(';') : ua.split(' ') - // eslint-disable-next-line no-useless-escape - const otherInfo = [ - /\bAndroid\b/i, - /\bLinux\b/i, - /\bU\b/i, - /^\s?[a-z][a-z]$/i, - /^\s?[a-z][a-z]-[a-z][a-z]$/i, - /\bwv\b/i, - /\/[\d\.,]+$/, - /^\s?[\d\.,]+$/, - /\bBrowser\b/i, - /\bMobile\b/i, - ] - for (let i = 0; i < infos.length; i++) { - const info = infos[i] - if (info.indexOf('Build') > 0) { - model = info.split('Build')[0].trim() - break - } - let other - for (let o = 0; o < otherInfo.length; o++) { - if (otherInfo[o].test(info)) { - other = true - break - } - } - if (!other) { - model = info.trim() - break - } - } - } else if (isIPadOS) { - model = 'iPad' - osname = 'iOS' - deviceType = 'pad' - osversion = typeof window.BigInt === 'function' ? '14.0' : '13.0' - } else if (isWindows || isMac || isLinux) { - model = 'PC' - osname = 'PC' - deviceType = 'pc' - osversion = '0' - - let osversionFind = ua.match(/\((.+?)\)/)![1] - if (isWindows) { - osname = 'Windows' - switch (isWindows[1]) { - case '5.1': - osversion = 'XP' - break - case '6.0': - osversion = 'Vista' - break - case '6.1': - osversion = '7' - break - case '6.2': - osversion = '8' - break - case '6.3': - osversion = '8.1' - break - case '10.0': - osversion = '10' - break - } + _initBrowserInfo = true + initBrowserInfo() + _initBrowserInfo = false + const windowInfo = getWindowInfo() + const deviceInfo = getDeviceInfo() + const appBaseInfo = getAppBaseInfo() + _initBrowserInfo = true - const framework = - osversionFind && osversionFind.match(/[Win|WOW]([\d]+)/) - if (framework) { - osversion += ` x${framework[1]}` - } - } else if (isMac) { - osname = 'Mac' - osversion = - (osversionFind && osversionFind.match(/Mac OS X (.+)/)) || '' - - if (osversion) { - osversion = osversion[1].replace(/_/g, '.') - // '10_15_7' or '10.16; rv:86.0' - if (osversion.indexOf(';') !== -1) { - osversion = osversion.split(';')[0] - } - } - } else if (isLinux) { - osname = 'Linux' - osversion = (osversionFind && osversionFind.match(/Linux (.*)/)) || '' - - if (osversion) { - osversion = osversion[1] - // 'x86_64' or 'x86_64; rv:79.0' - if (osversion.indexOf(';') !== -1) { - osversion = osversion.split(';')[0] - } - } - } - } else { - osname = 'Other' - osversion = '0' - deviceType = 'other' - } - - const system = `${osname} ${osversion}` - const platform = osname.toLocaleLowerCase() - const safeArea = { - left: safeAreaInsets.left, - right: windowWidth - safeAreaInsets.right, - top: safeAreaInsets.top, - bottom: windowHeight - safeAreaInsets.bottom, - width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, - height: windowHeight - safeAreaInsets.top - safeAreaInsets.bottom, - } - - const { top: windowTop, bottom: windowBottom } = getWindowOffset() - - windowHeight -= windowTop - windowHeight -= windowBottom - - let browserName = '' - let browseVersion = String(IEVersion()) - if (browseVersion !== '-1') { - browserName = 'IE' - } else { - const browseVendors = ['Version', 'Firefox', 'Chrome', 'Edge{0,1}'] - const vendors = ['Safari', 'Firefox', 'Chrome', 'Edge'] - for (let index = 0; index < browseVendors.length; index++) { - const vendor = browseVendors[index] - const reg = new RegExp(`(${vendor})/(\\S*)\\b`) - if (reg.test(ua)) { - browserName = vendors[index] - browseVersion = ua.match(reg)![2] - } - } - } - - // deviceBrand - let deviceBrand = '' - if (model) { - const _model = model.toLocaleLowerCase() - deviceBrand = - getDeviceBrand(_model) || - getDeviceBrand(osname.toLocaleLowerCase()) || - _model.split(' ')[0] - } - - return { - windowTop, - windowBottom, - windowWidth, - windowHeight, - pixelRatio, - screenWidth, - screenHeight, - language, - statusBarHeight, - system, - platform, - deviceBrand, - deviceType, - model, - safeArea, - safeAreaInsets: { - top: safeAreaInsets.top, - right: safeAreaInsets.right, - bottom: safeAreaInsets.bottom, - left: safeAreaInsets.left, - }, - version: __uniConfig.appVersion, - SDKVersion: '', - deviceId: deviceId(), + const { ua, - uniPlatform: 'web', + deviceType, browserName, browseVersion, - osLanguage: language, - osName: osname.toLocaleLowerCase(), - osVersion: osversion, - hostLanguage: language, - uniCompileVersion: __uniConfig.compilerVersion, - uniRuntimeVersion: __uniConfig.compilerVersion, - appId: __uniConfig.appId, - appName: __uniConfig.appName, - appVersion: __uniConfig.appVersion, - appVersionCode: __uniConfig.appVersionCode, - hostName: browserName, - hostVersion: browseVersion, - osTheme: '', - hostTheme: '', - hostPackageName: '', - } as UniApp.GetSystemInfoResult + osname, + osversion, + deviceOrientation, + } = browserInfo + const { pixelRatio } = windowInfo + + const systemInfo: UniApp.GetSystemInfoResult = extend( + windowInfo, + deviceInfo, + appBaseInfo, + { + ua, + deviceType, + browserName, + browseVersion, + deviceId: deviceId(), + devicePixelRatio: pixelRatio, + deviceOrientation, + uniPlatform: 'web', + uniCompileVersion: __uniConfig.compilerVersion, + uniRuntimeVersion: __uniConfig.compilerVersion, + fontSizeSetting: appBaseInfo.hostFontSizeSetting, + osName: osname!.toLocaleLowerCase(), + osVersion: osversion, + osLanguage: undefined, + osTheme: undefined, + } + ) + + delete (systemInfo as any).screenTop + delete (systemInfo as any).enableDebug + delete (systemInfo as any).theme + + return systemInfo } ) diff --git a/packages/uni-h5/src/service/api/device/getWindowInfo.ts b/packages/uni-h5/src/service/api/device/getWindowInfo.ts new file mode 100644 index 0000000000000000000000000000000000000000..39ddf63823c080ea52cd8d3df542c93a70fa2f3f --- /dev/null +++ b/packages/uni-h5/src/service/api/device/getWindowInfo.ts @@ -0,0 +1,58 @@ +import safeAreaInsets from 'safe-area-insets' +import { getWindowOffset } from '@dcloudio/uni-core' +import { + isLandscape, + getScreenFix, + getScreenWidth, + getWindowWidth, + getScreenHeight, +} from '../base/getBaseSystemInfo' +import { defineSyncApi } from '@dcloudio/uni-api' + +export const getWindowInfo = defineSyncApi( + 'getWindowInfo', + () => { + const pixelRatio = window.devicePixelRatio + // 横屏时 iOS 获取的屏幕宽高颠倒,进行纠正 + const screenFix = getScreenFix() + const landscape = isLandscape(screenFix) + const screenWidth = getScreenWidth(screenFix, landscape) + const screenHeight = getScreenHeight(screenFix, landscape) + const windowWidth = getWindowWidth(screenWidth) + let windowHeight = window.innerHeight + const statusBarHeight = safeAreaInsets.top + + const safeArea = { + left: safeAreaInsets.left, + right: windowWidth - safeAreaInsets.right, + top: safeAreaInsets.top, + bottom: windowHeight - safeAreaInsets.bottom, + width: windowWidth - safeAreaInsets.left - safeAreaInsets.right, + height: windowHeight - safeAreaInsets.top - safeAreaInsets.bottom, + } + + const { top: windowTop, bottom: windowBottom } = getWindowOffset() + + windowHeight -= windowTop + windowHeight -= windowBottom + + return { + windowTop, + windowBottom, + windowWidth, + windowHeight, + pixelRatio, + screenWidth, + screenHeight, + statusBarHeight, + safeArea, + safeAreaInsets: { + top: safeAreaInsets.top, + right: safeAreaInsets.right, + bottom: safeAreaInsets.bottom, + left: safeAreaInsets.left, + }, + screenTop: screenHeight - windowHeight, + } + } +) diff --git a/packages/uni-h5/src/service/api/index.ts b/packages/uni-h5/src/service/api/index.ts index c0722e61ce4f38a7ed7f33c51a487b13635e1ef8..15fa1b647fe965775bcbe8ec95ed623ee7386d30 100644 --- a/packages/uni-h5/src/service/api/index.ts +++ b/packages/uni-h5/src/service/api/index.ts @@ -21,6 +21,7 @@ export * from './device/accelerometer' export * from './device/compass' export * from './device/vibrate' export * from './device/clipboard' +export * from './device/getWindowInfo' export * from './storage/storage' diff --git a/packages/uni-mp-core/src/api/protocols/enhanceSystemInfo.ts b/packages/uni-mp-core/src/api/protocols/enhanceSystemInfo.ts index 2d3dc8015f027c0b8f3c6dbc4cc4210736ec2f0e..bf44e31895dca18b688f17339b4b539d7f821296 100644 --- a/packages/uni-mp-core/src/api/protocols/enhanceSystemInfo.ts +++ b/packages/uni-mp-core/src/api/protocols/enhanceSystemInfo.ts @@ -54,8 +54,13 @@ export function populateParameters( language, theme, version, - hostName = '', + hostName, platform, + fontSizeSetting, + SDKVersion, + pixelRatio, + deviceOrientation, + environment, } = fromRes const isQuickApp = __PLATFORM__.indexOf('quickapp-webview') !== -1 @@ -72,7 +77,10 @@ export function populateParameters( let hostVersion = version // host 枚举值 https://smartprogram.baidu.com/docs/develop/api/device_sys/hostlist/ if (__PLATFORM__ === 'mp-baidu') { - hostVersion = fromRes.swanNativeVersion || version + hostVersion = fromRes.swanNativeVersion + } + if (__PLATFORM__ === 'mp-jd') { + hostVersion = fromRes.hostVersionName } // deviceType @@ -110,15 +118,41 @@ export function populateParameters( } // hostName - let _hostName = hostName // mp-jd - if (__PLATFORM__ === 'mp-weixin') _hostName = (fromRes.host || {}).env - if (__PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-kuaishou') + let _hostName = hostName || __PLATFORM__.split('-')[1] // mp-jd + if (__PLATFORM__ === 'mp-weixin') { + if (environment) { + _hostName = environment + } else if (fromRes.host) { + _hostName = fromRes.host.env + } + } + if (__PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-kuaishou') { _hostName = fromRes.host + } if (__PLATFORM__ === 'mp-qq') _hostName = fromRes.AppPlatform - if (__PLATFORM__ === 'mp-toutiao' || __PLATFORM__ === 'mp-lark') + if (__PLATFORM__ === 'mp-toutiao' || __PLATFORM__ === 'mp-lark') { _hostName = fromRes.appName + } if (__PLATFORM__ === 'mp-alipay') _hostName = fromRes.app + // deviceOrientation + let _deviceOrientation = deviceOrientation // 仅 微信 百度 支持 + if (__PLATFORM__ === 'mp-baidu') { + _deviceOrientation = fromRes.orientation + } + + // devicePixelRatio + let _devicePixelRatio = pixelRatio + if (__PLATFORM__ === 'mp-baidu') { + _devicePixelRatio = fromRes.devicePixelRatio + } + + // SDKVersion + let _SDKVersion = SDKVersion + if (__PLATFORM__ === 'mp-alipay') { + _SDKVersion = my.SDKVersion + } + // wx.getAccountInfoSync const parameters = { @@ -132,19 +166,25 @@ export function populateParameters( deviceBrand, deviceModel: model, deviceType, + devicePixelRatio: _devicePixelRatio, + deviceOrientation: _deviceOrientation, osName: osName.toLocaleLowerCase(), osVersion, - osLanguage: language, - osTheme: theme, hostTheme: theme, hostVersion, - hostLanguage: language, + hostLanguage: language.split('_', '-'), hostName: _hostName, + hostSDKVersion: _SDKVersion, + hostFontSizeSetting: fontSizeSetting, + windowTop: 0, + windowBottom: 0, // TODO - ua: '', - hostPackageName: '', - browserName: '', - browseVersion: '', + osLanguage: undefined, + osTheme: undefined, + ua: undefined, + hostPackageName: undefined, + browserName: undefined, + browseVersion: undefined, } extend(toRes, parameters)