提交 30bce912 编写于 作者: Q qiang

Merge branch 'dev' into alpha

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=n()}(this,function(){"use strict";function i(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(window.__dcloud_weex_postMessage||window.__dcloud_weex_){if("postMessage"===e){var t={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(t):window.__dcloud_weex_.postMessage(JSON.stringify(t))}var o={type:c,args:{data:i,webviewIds:w}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(o):window.__dcloud_weex_.postMessageToService(JSON.stringify(o))}if(!window.plus)return window.parent.postMessage({type:c,data:i,pageId:""},"*");if(0===w.length){var a=plus.webview.currentWebview();if(!a)throw new Error("plus.webview.currentWebview() is undefined");var d=a.parent(),r="";r=d?d.id:a.id,w.push(r)}if(plus.webview.getWebviewById(u))plus.webview.postMessageToUniNView({type:c,args:{data:i,webviewIds:w}},u);else{var s=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat(c,'",').concat(s,",").concat(JSON.stringify(w),");"))}}var w=[],u="__uniapp__service",c="WEB_INVOKE_APPSERVICE",n={navigateTo:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("navigateTo",{url:encodeURI(n)})},navigateBack:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).delta;i("navigateBack",{delta:parseInt(n)||1})},switchTab:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("switchTab",{url:encodeURI(n)})},reLaunch:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("reLaunch",{url:encodeURI(n)})},redirectTo:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("redirectTo",{url:encodeURI(n)})},getEnv:function(e){window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(e){i("postMessage",(0<arguments.length&&void 0!==e?e:{}).data||{})}},t=/uni-app/i.test(navigator.userAgent),o=/complete|loaded|interactive/;var a=window.my&&-1<navigator.userAgent.indexOf("AlipayClient");var d=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var r=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var s=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var g=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);for(var e,v=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},p=[function(e){if(t)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&o.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),n},function(e){if(g)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(r)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(a){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(d)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(s)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),n}],l=0;l<p.length&&!(e=p[l](v));l++);e=e||{};var f="undefined"!=typeof uni?uni:{};return f.navigateTo?f.webView=e:Object.assign(f,e,{webView:e}),f});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=n()}(this,function(){"use strict";function i(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(window.__dcloud_weex_postMessage||window.__dcloud_weex_){if("postMessage"===e){var t={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(t):window.__dcloud_weex_.postMessage(JSON.stringify(t))}var o={type:c,args:{data:i,webviewIds:w}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(o):window.__dcloud_weex_.postMessageToService(JSON.stringify(o))}if(!window.plus)return window.parent.postMessage({type:c,data:i,pageId:""},"*");if(0===w.length){var a=plus.webview.currentWebview();if(!a)throw new Error("plus.webview.currentWebview() is undefined");var d=a.parent(),r="";r=d?d.id:a.id,w.push(r)}if(plus.webview.getWebviewById(u))plus.webview.postMessageToUniNView({type:c,args:{data:i,webviewIds:w}},u);else{var s=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat(c,'",').concat(s,",").concat(JSON.stringify(w),");"))}}var w=[],u="__uniapp__service",c="WEB_INVOKE_APPSERVICE",n={navigateTo:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("navigateTo",{url:encodeURI(n)})},navigateBack:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).delta;i("navigateBack",{delta:parseInt(n)||1})},switchTab:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("switchTab",{url:encodeURI(n)})},reLaunch:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("reLaunch",{url:encodeURI(n)})},redirectTo:function(e){var n=(0<arguments.length&&void 0!==e?e:{}).url;i("redirectTo",{url:encodeURI(n)})},getEnv:function(e){window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(e){i("postMessage",(0<arguments.length&&void 0!==e?e:{}).data||{})}},t=/uni-app/i.test(navigator.userAgent),o=/complete|loaded|interactive/;var a=window.my&&-1<navigator.userAgent.indexOf("AlipayClient");var d=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var r=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var s=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var g=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);for(var e,v=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},p=[function(e){if(t)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&o.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),n},function(e){if(g)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(r)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(a){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(d)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(s)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),n}],l=0;l<p.length&&!(e=p[l](v));l++);e=e||{};var f="undefined"!=typeof uni?uni:{};if(!f.navigateTo)for(var _ in e)e.hasOwnProperty(_)&&(f[_]=e[_]);return f.webView=e,f});
......@@ -123,7 +123,9 @@ const PLATFORMS = {
} = getH5Options()
const to = path.join(assetsDir, `[name].${VUE_APP_INDEX_CSS_HASH}.[ext]`)
if (process.env.NODE_ENV === 'production') {
const templateContent = fs.readFileSync(template, { encoding: 'utf8' })
const templateContent = fs.readFileSync(template, {
encoding: 'utf8'
})
if (/\bVUE_APP_INDEX_CSS_HASH\b/.test(templateContent)) {
indexCssCopyOptions[0].to = to
}
......@@ -152,9 +154,7 @@ const PLATFORMS = {
megalo: false,
filterTag: 'wxs',
subPackages: false,
cssVars: {
'--window-top': '0px'
},
cssVars: {},
copyWebpackOptions ({
assetsDir,
vueOptions
......@@ -584,5 +584,18 @@ module.exports = {
},
getPlatformSass () {
return SASS
},
getBabelParserOptions () {
return {
sourceType: 'module',
plugins: [
'optionalChaining',
'typescript',
['decorators', {
decoratorsBeforeExport: true
}],
'classProperties'
]
}
}
}
}
......@@ -39,7 +39,11 @@ module.exports = function migrate(input, out, options = {}) {
)
) {
options.silent !== true && console.log(`copy: ${dest}`)
src !== dest && fs.copySync(src, dest)
try {
fs.copySync(src, dest)
} catch (e) {
//ignore Source and destination must not be the same
}
}
} else {
options.silent !== true && console.log(`write: ${path.resolve(out, asset.path)}`)
......
......@@ -385,11 +385,28 @@ var previewImage = {
}
};
function addSafeAreaInsets (result) {
if (result.safeArea) {
const safeArea = result.safeArea;
result.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: result.windowWidth - safeArea.right,
bottom: result.windowHeight - safeArea.bottom
};
}
}
const protocols = {
previewImage
previewImage,
getSystemInfo: {
returnValue: addSafeAreaInsets
},
getSystemInfoSync: {
returnValue: addSafeAreaInsets
}
};
const todos = [
'vibrate'
const todos = [
'vibrate'
];
const canIUses = [];
......
......@@ -239,14 +239,6 @@ var VAR_WINDOW_BOTTOM = /var\(--window-bottom\)/gi
function processCss(css) {
var envMethod = ''
envMethod = uni.canIUse('css.constant') ? 'constant' : envMethod
envMethod = uni.canIUse('css.env') ? 'env' : envMethod
if (envMethod) {
css = css.replace(VAR_STATUS_BAR_HEIGHT, envMethod + '(safe-area-inset-top)')
.replace(VAR_WINDOW_TOP, 'calc(var(--window-top) + ' + envMethod + '(safe-area-inset-top))')
.replace(VAR_WINDOW_BOTTOM, 'calc(var(--window-bottom) + ' + envMethod + '(safe-area-inset-bottom))')
}
var page = getPage()
if (!uni.canIUse('css.var')) { //不支持 css 变量
var offset = getWindowOffset()
......
......@@ -13,6 +13,10 @@ const {
jsPreprocessOptions
} = require('@dcloudio/uni-cli-shared')
const {
getBabelParserOptions
} = require('@dcloudio/uni-cli-shared/lib/platform')
const {
updateUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/cache')
......@@ -55,14 +59,14 @@ module.exports = function (content) {
const vuePagePath = path.resolve(process.env.UNI_INPUT_DIR, normalizePath(params.page) + '.vue')
if (!fs.existsSync(vuePagePath)) {
const nvuePagePath = path.resolve(process.env.UNI_INPUT_DIR, normalizePath(params.page) +
'.nvue')
'.nvue')
if (fs.existsSync(nvuePagePath)) {
ext = '.nvue'
}
}
}
return `
import Vue from 'vue'
import Vue from 'vue'
import Page from './${normalizePath(params.page)}${ext}'
createPage(Page)
`
......@@ -78,16 +82,7 @@ createPage(Page)
state: {
components
}
} = traverse(parser.parse(content, {
sourceType: 'module',
plugins: [
'typescript',
['decorators', {
decoratorsBeforeExport: true
}],
'classProperties'
]
}), {
} = traverse(parser.parse(content, getBabelParserOptions()), {
components: []
})
......
......@@ -10,6 +10,10 @@ const {
jsPreprocessOptions
} = require('@dcloudio/uni-cli-shared')
const {
getBabelParserOptions
} = require('@dcloudio/uni-cli-shared/lib/platform')
const {
updateUsingComponents
} = require('@dcloudio/uni-cli-shared/lib/cache')
......@@ -63,16 +67,7 @@ module.exports = function (content, map) {
state: {
components
}
} = traverse(parser.parse(content, {
sourceType: 'module',
plugins: [
'typescript',
['decorators', {
decoratorsBeforeExport: true
}],
'classProperties'
]
}), {
} = traverse(parser.parse(content, getBabelParserOptions()), {
type,
components: []
})
......
......@@ -96,9 +96,22 @@ const getPageComponents = function (inputDir, pagesJson) {
}
let windowTop = 44
let pageStyle = Object.assign({}, globalStyle, props)
if (pageStyle.navigationStyle === 'custom' || ('titleNView' in pageStyle && (!pageStyle.titleNView || pageStyle.titleNView.type ===
'transparent' || pageStyle.titleNView.type === 'float'))) {
const pageStyle = Object.assign({}, globalStyle, props)
const titleNViewTypeList = {
'none': 'default',
'auto': 'transparent',
'always': 'float'
}
let titleNView = pageStyle.titleNView
titleNView = Object.assign({}, {
type: pageStyle.navigationStyle === 'custom' ? 'none' : 'default'
}, pageStyle.transparentTitle in titleNViewTypeList ? {
type: titleNViewTypeList[pageStyle.transparentTitle],
backgroundColor: 'rgba(0,0,0,0)'
} : null, typeof titleNView === 'object' ? titleNView : (typeof titleNView === 'boolean' ? {
type: titleNView ? 'default' : 'none'
} : null))
if (titleNView.type === 'none' || titleNView.type === 'transparent') {
windowTop = 0
}
......@@ -300,7 +313,7 @@ module.exports = function (pagesJson, manifestJson) {
const inputDir = process.env.UNI_INPUT_DIR
const pageComponents = getPageComponents(inputDir, pagesJson)
pagesJson.globalStyle = process.UNI_H5_PAGES_JSON.globalStyle
delete pagesJson.pages
delete pagesJson.subPackages
......
......@@ -52,12 +52,13 @@ if (!webViewApi) {
const api = typeof uni !== 'undefined' ? uni : {}
if (api.navigateTo) {
api.webView = webViewApi
} else {
Object.assign(api, webViewApi, {
webView: webViewApi
})
if (!api.navigateTo) {
for (const key in webViewApi) {
if (webViewApi.hasOwnProperty(key)) {
api[key] = webViewApi[key]
}
}
}
api.webView = webViewApi
export default api
import {
callApiSync,
isTabBarPage,
getLastWebview
getLastWebview,
getStatusbarHeight,
getScreenInfo
} from '../util'
import {
......@@ -17,48 +19,55 @@ export function getSystemInfoSync () {
export function getSystemInfo () {
const platform = plus.os.name.toLowerCase()
const ios = platform === 'ios'
// 安卓 plus 接口获取的屏幕大小值不为整数,iOS js 获取的屏幕大小横屏时颠倒
const screenWidth = plus.screen.resolutionWidth
const screenHeight = plus.screen.resolutionHeight
// 横屏时 iOS 获取的状态栏高度错误,进行纠正
var landscape = Math.abs(plus.navigator.getOrientation()) === 90
var statusBarHeight = Math.round(plus.navigator.getStatusbarHeight())
if (ios && landscape) {
statusBarHeight = Math.min(20, statusBarHeight)
}
var safeAreaInsets
function getSafeAreaInsets () {
return {
left: 0,
right: 0,
top: titleNView ? 0 : statusBarHeight,
bottom: 0
}
const {
screenWidth,
screenHeight
} = getScreenInfo()
const statusBarHeight = getStatusbarHeight()
let safeAreaInsets
const titleNView = {
height: 0,
cover: false
}
// 判断是否存在 titleNView
var titleNView
var webview = getLastWebview()
const webview = getLastWebview()
if (webview) {
let style = webview.getStyle()
if (style) {
titleNView = style && style.titleNView
titleNView = titleNView && titleNView.type === 'default'
style = style && style.titleNView
if (style && style.type && style.type !== 'none') {
titleNView.height = style.type === 'transparent' ? 0 : (statusBarHeight + TITLEBAR_HEIGHT)
titleNView.cover = style.type === 'transparent' || style.type === 'float'
}
safeAreaInsets = ios ? webview.getSafeAreaInsets() : getSafeAreaInsets()
safeAreaInsets = webview.getSafeAreaInsets()
} else {
safeAreaInsets = ios ? plus.navigator.getSafeAreaInsets() : getSafeAreaInsets()
safeAreaInsets = plus.navigator.getSafeAreaInsets()
}
var windowBottom = isTabBarPage() && tabBar.visible && tabBar.cover ? tabBar.height : 0
var windowHeight = Math.min(screenHeight - (titleNView ? (statusBarHeight + TITLEBAR_HEIGHT)
: 0) - windowBottom, screenHeight)
var windowWidth = screenWidth
var safeArea = {
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
const windowHeight = screenHeight - titleNView.height - tabBarView.height
const windowHeightReal = screenHeight - (titleNView.cover ? 0 : titleNView.height) - (tabBarView.cover ? 0 : tabBarView.height)
const windowWidth = screenWidth
safeAreaInsets = ios ? safeAreaInsets : {
left: 0,
right: 0,
top: titleNView.height && !titleNView.cover ? 0 : statusBarHeight,
bottom: 0
}
const safeArea = {
left: safeAreaInsets.left,
right: windowWidth - safeAreaInsets.right,
top: safeAreaInsets.top,
bottom: windowHeight - safeAreaInsets.bottom,
bottom: windowHeightReal - safeAreaInsets.bottom,
width: windowWidth - safeAreaInsets.left - safeAreaInsets.right,
height: windowHeight - safeAreaInsets.top - safeAreaInsets.bottom
height: windowHeightReal - safeAreaInsets.top - safeAreaInsets.bottom
}
return {
......@@ -77,8 +86,14 @@ export function getSystemInfo () {
fontSizeSetting: '',
platform,
SDKVersion: '',
windowTop: 0,
windowTop,
windowBottom,
safeArea
safeArea,
safeAreaInsets: {
top: safeAreaInsets.top,
right: safeAreaInsets.right,
bottom: safeAreaInsets.bottom,
left: safeAreaInsets.left
}
}
}
export {
isTabBarPage
} from '../bridge'
export {
isTabBarPage
} from '../bridge'
export function callApiSync (api, args, name, alias) {
const ret = api(args)
if (ret && ret.errMsg) {
......@@ -148,4 +148,22 @@ const _transformlng = function (lng, lat) {
const outOfChina = function (lng, lat) {
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false)
}
}
export function getStatusbarHeight () {
// 横屏时 iOS 获取的状态栏高度错误,进行纠正
return plus.navigator.isImmersedStatusbar() ? Math.round(plus.os.name === 'iOS' ? plus.navigator.getSafeAreaInsets().top : plus.navigator.getStatusbarHeight()) : 0
}
export function getScreenInfo () {
const orientation = plus.navigator.getOrientation()
const landscape = Math.abs(orientation) === 90
// 安卓 plus 接口获取的屏幕大小值不为整数
const width = plus.screen.resolutionWidth
const height = plus.screen.resolutionHeight
// 根据方向纠正宽高
return {
screenWidth: Math[landscape ? 'max' : 'min'](width, height),
screenHeight: Math[landscape ? 'min' : 'max'](width, height)
}
}
......@@ -5,7 +5,7 @@ import {
const isAndroid = plus.os.name.toLowerCase() === 'android'
const FOCUS_TIMEOUT = isAndroid ? 300 : 700
const HIDE_TIMEOUT = 300
const HIDE_TIMEOUT = 800
let keyboardHeight = 0
let onKeyboardShow
let focusTimer
......
......@@ -16,12 +16,17 @@ import {
from 'uni-core/service/plugins/lifecycle'
import {
ON_REACH_BOTTOM_DISTANCE
ON_REACH_BOTTOM_DISTANCE,
TITLEBAR_HEIGHT
}
from '../../constants'
import tabBar from '../tab-bar'
import {
getStatusbarHeight
} from '../../api/util'
function parsePageCreateOptions (vm, route) {
const pagePath = '/' + route
const routeOptions = __uniRoutes.find(route => route.path === pagePath)
......@@ -34,13 +39,15 @@ function parsePageCreateOptions (vm, route) {
const onPageScroll = hasLifecycleHook(vm.$options, 'onPageScroll') ? 1 : 0
const onPageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom') ? 1 : 0
const statusbarHeight = getStatusbarHeight()
return {
disableScroll,
onPageScroll,
onPageReachBottom,
onReachBottomDistance,
windowTop: 0, // TODO
statusbarHeight,
windowTop: windowOptions.titleNView && windowOptions.titleNView.type === 'float' ? (statusbarHeight + TITLEBAR_HEIGHT) : 0,
windowBottom: (tabBar.indexOf(route) >= 0 && tabBar.cover) ? tabBar.height : 0
}
}
......@@ -88,4 +95,4 @@ export function initLifecycle (Vue) {
}
}
})
}
}
......@@ -10,6 +10,10 @@ import {
isTabBarPage
} from '../../../bridge'
import {
getStatusbarHeight
} from '../../../api/util'
import tabBar from '../../tab-bar'
function initPopupSubNVue (subNVueWebview, style, maskWebview) {
......@@ -96,7 +100,7 @@ function initSubNVue (subNVue, routeOptions, webview) {
style.dock = 'top'
style.top = 0
style.width = '100%'
style.height = TITLEBAR_HEIGHT + plus.navigator.getStatusbarHeight()
style.height = TITLEBAR_HEIGHT + getStatusbarHeight()
delete style.left
delete style.right
delete style.bottom
......
......@@ -20,6 +20,7 @@ const passiveOptions = supportsPassive ? {
} : false
function onCssVar ({
statusbarHeight,
windowTop,
windowBottom
}) {
......@@ -29,8 +30,9 @@ function onCssVar ({
const style = document.documentElement.style
style.setProperty('--window-top', windowTop + 'px')
style.setProperty('--window-bottom', windowBottom + 'px')
style.setProperty('--status-bar-height', plus.navigator.getStatusbarHeight() + 'px')
style.setProperty('--status-bar-height', statusbarHeight + 'px')
if (process.env.NODE_ENV !== 'production') {
console.log(`--status-bar-height=${statusbarHeight}`)
console.log(`--window-top=${windowTop}`)
console.log(`--window-bottom=${windowBottom}`)
}
......@@ -38,6 +40,7 @@ function onCssVar ({
}
function onPageCreate ({
statusbarHeight,
windowTop,
windowBottom,
disableScroll,
......@@ -46,6 +49,7 @@ function onPageCreate ({
onReachBottomDistance
}, pageId) {
onCssVar({
statusbarHeight,
windowTop,
windowBottom
})
......@@ -70,4 +74,4 @@ function onWebviewReady () { // service 主动发起检测
export default function initSubscribe (subscribe) {
subscribe(WEBVIEW_READY, onWebviewReady)
subscribe(ON_PAGE_CREATE, onPageCreate)
}
}
......@@ -162,12 +162,8 @@ export default {
this.map && this.map[val ? 'hide' : 'show']()
}
},
listeners: {
'@view-update': '_requestUpdate'
},
mounted () {
this._updateStyle()
let mapStyle = Object.assign({}, this.attrs, this.style)
let mapStyle = Object.assign({}, this.attrs, this.position)
if (this.latitude && this.longitude) {
mapStyle.center = new plus.maps.Point(this.longitude, this.latitude)
}
......@@ -180,12 +176,18 @@ export default {
map.hide()
}
this.$watch('attrs', () => {
this.map && this.map.setStyles(this.attrs)
if (this.map) {
this.map.setStyles(this.attrs)
// TODO 临时处理更新 longitude, latitude 无效问题
this.map.setStyles({
center: new plus.maps.Point(this.longitude, this.latitude)
})
}
}, {
deep: true
})
this.$watch('style', () => {
this.map && this.map.setStyles(this.style)
this.$watch('position', () => {
this.map && this.map.setStyles(this.position)
}, {
deep: true
})
......@@ -213,35 +215,8 @@ export default {
this.map && this[type](data)
},
getRegion () {
// TODO
// const region = this.map.getBounds()
},
getScale () {
// TODO
// const zoom = this.map.getZoom()
},
_updateStyle () {
const rect = this.$refs.container.getBoundingClientRect()
this.hidden = false;
['top', 'left', 'width', 'height'].forEach(key => {
let val = rect[key]
val = key === 'top' ? val + (document.documentElement.scrollTop || document.body.scrollTop || 0) : val
if (!val && (key === 'width' || key === 'height')) {
this.hidden = true
}
this.style[key] = val + 'px'
})
},
_requestUpdate () {
if (this._animationFrame) {
cancelAnimationFrame(this._animationFrame)
}
if (this.video) {
this._animationFrame = requestAnimationFrame(() => {
delete this._animationFrame
this._updateStyle()
})
}
},
controlclick (e) {
this.$trigger('controltap', {}, { id: e.id })
......
<template>
<uni-page :data-page="$route.meta.pagePath">
<page-head
v-if="showNavigationBar"
<page-head
v-if="navigationBar.type!=='none'"
v-bind="navigationBar" />
<page-refresh
v-if="enablePullDownRefresh"
ref="refresh"
:color="refreshOptions.color"
:offset="refreshOptions.offset" />
:offset="refreshOptions.offset"
/>
<page-body
v-if="enablePullDownRefresh"
@touchstart.native="_touchstart"
@touchmove.native="_touchmove"
@touchend.native="_touchend"
@touchcancel.native="_touchend">
@touchcancel.native="_touchend"
>
<slot name="page" />
</page-body>
<page-body v-else>
......@@ -22,11 +24,11 @@
</uni-page>
</template>
<style>
uni-page {
display: block;
width: 100%;
height: 100%;
}
uni-page {
display: block;
width: 100%;
height: 100%;
}
</style>
<script>
import {
......@@ -47,6 +49,8 @@ import PageRefresh from './pageRefresh'
import pullToRefresh from './pull-to-refresh'
import safeAreaInsets from 'safe-area-insets'
export default {
name: 'Page',
mpType: 'page',
......@@ -124,55 +128,61 @@ export default {
default: false
},
titleNView: {
type: [Boolean, Object],
default: true
type: [Boolean, Object, String],
default: ''
},
pullToRefresh: {
type: Object,
default () {
return {}
}
},
titleImage: {
type: String,
default: ''
},
transparentTitle: {
type: String,
default: 'none'
},
titlePenetrate: {
type: String,
default: 'NO'
},
titleImage: {
type: String,
default: ''
},
transparentTitle: {
type: String,
default: ''
},
titlePenetrate: {
type: String,
default: 'NO'
}
},
data () {
const titleNViewTypeList = {
'none': 'default',
'auto': 'transparent',
'always': 'float'
}
const yesNoParseList = {
'YES': true,
'NO': false
}
data () {
const titleNViewTypeList = {
'none': 'default',
'auto': 'transparent',
'always': 'float'
}
// 将 navigationStyle 和 transparentTitle 都合并到 titleNView
let titleNView = this.titleNView
titleNView = Object.assign({}, {
type: this.navigationStyle === 'custom' ? 'none' : 'default'
}, this.transparentTitle in titleNViewTypeList ? {
type: titleNViewTypeList[this.transparentTitle],
backgroundColor: 'rgba(0,0,0,0)'
} : null, typeof titleNView === 'object' ? titleNView : (typeof titleNView === 'boolean' ? {
type: titleNView ? 'default' : 'none'
} : null))
const yesNoParseList = {
'YES': true,
'NO': false
}
const navigationBar = mergeTitleNView({
loading: false,
backButton: !this.isQuit && !this.$route.meta.isQuit, // redirectTo,reLaunch时可能动态修改 meta.isQuit
backgroundColor: this.navigationBarBackgroundColor,
textColor: this.navigationBarTextStyle === 'black' ? '#000' : '#fff',
titleText: this.navigationBarTitleText,
titleText: this.navigationBarTitleText,
titleImage: this.titleImage,
duration: '0',
timingFunc: '',
type: titleNViewTypeList[this.transparentTitle],
transparentTitle: this.transparentTitle,
timingFunc: '',
titlePenetrate: yesNoParseList[this.titlePenetrate]
}, this.titleNView)
const showNavigationBar = this.navigationStyle === 'default' && this.titleNView
}, titleNView)
const refreshOptions = Object.assign({
support: true,
......@@ -185,10 +195,8 @@ export default {
let offset = upx2px(refreshOptions.offset)
if (showNavigationBar) {
if (!(this.titleNView && this.titleNView.type === 'transparent')) {
offset += NAVBAR_HEIGHT
}
if (titleNView.type !== 'none' && titleNView.type !== 'transparent') {
offset += NAVBAR_HEIGHT + safeAreaInsets.top
}
refreshOptions.offset = offset
......@@ -196,7 +204,6 @@ export default {
refreshOptions.range = upx2px(refreshOptions.range)
return {
showNavigationBar,
navigationBar,
refreshOptions
}
......
......@@ -14,6 +14,8 @@ uni-page-wrapper {
uni-page-head[uni-page-head-type="default"] ~ uni-page-wrapper {
height: calc(100% - 44px);
height: calc(100% - 44px - constant(safe-area-inset-top));
height: calc(100% - 44px - env(safe-area-inset-top));
}
.uni-app--showtabbar uni-page-wrapper {
......@@ -34,8 +36,8 @@ uni-page-head[uni-page-head-type="default"] ~ uni-page-wrapper {
.uni-app--showtabbar uni-page-head[uni-page-head-type="default"] ~ uni-page-wrapper {
height: calc(100% - 44px - 50px);
height: calc(100% - 44px - 50px - constant(safe-area-inset-bottom));
height: calc(100% - 44px - 50px - env(safe-area-inset-bottom));
height: calc(100% - 44px - constant(safe-area-inset-top) - 50px - constant(safe-area-inset-bottom));
height: calc(100% - 44px - env(safe-area-inset-top) - 50px - env(safe-area-inset-bottom));
}
uni-page-body {
......
......@@ -41,14 +41,12 @@
>
<i
v-if="loading"
class="uni-loading"/>
<img
v-if="titleImage!==''"
:src="titleImage"
class="uni-page-head__title_image" >
<template v-else>
{{ titleText }}
</template>
class="uni-loading" />
<img
v-if="titleImage!==''"
:src="titleImage"
class="uni-page-head__title_image" >
<template v-else>{{ titleText }}</template>
</div>
</div>
<div
......@@ -95,10 +93,11 @@
</template>
</div>
</div>
<div
<div
v-if="type!=='transparent'&&type!=='float'"
:class="{'uni-placeholder-titlePenetrate': titlePenetrate}"
class="uni-placeholder"/>
class="uni-placeholder"
/>
</uni-page-head>
</template>
<style>
......@@ -112,7 +111,11 @@ uni-page-head .uni-page-head {
left: 0;
width: 100%;
height: 44px;
height: calc(44px + constant(safe-area-inset-top));
height: calc(44px + env(safe-area-inset-top));
padding: 7px 3px;
padding-top: calc(7px + constant(safe-area-inset-top));
padding-top: calc(7px + env(safe-area-inset-top));
display: flex;
overflow: hidden;
justify-content: space-between;
......@@ -121,16 +124,16 @@ uni-page-head .uni-page-head {
color: #fff;
background-color: #000;
transition-property: all;
}
uni-page-head .uni-page-head-titlePenetrate,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd * {
pointer-events: none;
}
uni-page-head .uni-page-head-titlePenetrate *{
pointer-events: auto;
}
uni-page-head .uni-page-head-titlePenetrate,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd,
uni-page-head .uni-page-head-titlePenetrate .uni-page-head-bd * {
pointer-events: none;
}
uni-page-head .uni-page-head-titlePenetrate * {
pointer-events: auto;
}
uni-page-head .uni-page-head.uni-page-head-transparent .uni-page-head-ft > div {
......@@ -140,10 +143,12 @@ uni-page-head .uni-page-head.uni-page-head-transparent .uni-page-head-ft > div {
uni-page-head .uni-page-head ~ .uni-placeholder {
width: 100%;
height: 44px;
}
uni-page-head .uni-placeholder-titlePenetrate{
pointer-events: none;
height: calc(44px + constant(safe-area-inset-top));
height: calc(44px + env(safe-area-inset-top));
}
uni-page-head .uni-placeholder-titlePenetrate {
pointer-events: none;
}
uni-page-head .uni-page-head * {
......@@ -288,12 +293,12 @@ uni-page-head .uni-page-head__title .uni-loading {
width: 16px;
height: 16px;
margin-top: -3px;
}
uni-page-head .uni-page-head__title .uni-page-head__title_image {
width: auto;
height: 26px;
vertical-align: middle;
}
uni-page-head .uni-page-head__title .uni-page-head__title_image {
width: auto;
height: 26px;
vertical-align: middle;
}
</style>
<script>
......@@ -321,7 +326,9 @@ export default {
},
backgroundColor: {
type: String,
default: '#000'
default () {
return this.type === 'transparent' ? '#000' : '#F8F8F8'
}
},
textColor: {
type: String,
......@@ -368,20 +375,14 @@ export default {
default () {
return false
}
},
titleImage: {
type: String,
default: ''
},
transparentTitle: {
default: 'none',
validator (value) {
return ['none', 'auto', 'always'].indexOf(value) !== -1
}
},
titlePenetrate: {
type: Boolean,
default: false
},
titleImage: {
type: String,
default: ''
},
titlePenetrate: {
type: Boolean,
default: false
}
},
data () {
......
......@@ -52,7 +52,7 @@ export default {
borderRadiusElemStyle.backgroundColor = `rgba(${rgba})`
})
})
} else if (this.transparentTitle === 'always') {
} else if (this.type === 'float') {
const iconElems = this.$el.querySelectorAll('.uni-btn-icon')
const iconElemsStyles = []
for (let i = 0; i < iconElems.length; i++) {
......@@ -70,13 +70,13 @@ export default {
},
computed: {
color () {
return this.type === 'transparent' || this.transparentTitle === 'always' ? '#fff' : this.textColor
return this.type === 'transparent' ? '#fff' : this.textColor
},
offset () {
return parseInt(this.coverage)
},
bgColor () {
if (this.type === 'transparent' || this.transparentTitle === 'always') {
if (this.type === 'transparent') {
const {
r,
g,
......
......@@ -7,9 +7,11 @@ import safeAreaInsets from 'safe-area-insets'
export default function getWindowOffset () {
if (uni.canIUse('css.var')) {
const style = document.documentElement.style
const top = parseInt((style.getPropertyValue('--window-top').match(/\d+/) || ['0'])[0])
const bottom = parseInt((style.getPropertyValue('--window-bottom').match(/\d+/) || ['0'])[0])
return {
top: (parseInt(style.getPropertyValue('--window-top')) || 0) + safeAreaInsets.top,
bottom: (parseInt(style.getPropertyValue('--window-bottom')) || 0) + safeAreaInsets.bottom
top: top ? (top + safeAreaInsets.top) : 0,
bottom: bottom ? (bottom + safeAreaInsets.bottom) : 0
}
}
......@@ -18,7 +20,8 @@ export default function getWindowOffset () {
const pages = getCurrentPages()
if (pages.length) {
const pageVm = pages[pages.length - 1].$parent.$parent
top = pageVm.showNavigationBar && (pageVm.navigationBar.type !== 'transparent' || pageVm.navigationBar.type !== 'float') ? NAVBAR_HEIGHT : 0
const navigationBarType = pageVm.navigationBar.type
top = navigationBarType === 'default' || navigationBarType === 'float' ? NAVBAR_HEIGHT : 0
}
const app = getApp()
if (app) {
......
......@@ -21,7 +21,7 @@ export function getSystemInfoSync () {
var screenWidth = screen.width
var screenHeight = screen.height
var language = navigator.language
var statusBarHeight = 0
var statusBarHeight = safeAreaInsets.top
var osname
var osversion
var model
......@@ -84,7 +84,7 @@ export function getSystemInfoSync () {
const {
top: windowTop,
bottom: windowBottom
} = getWindowOffset(false, true)
} = getWindowOffset()
windowHeight -= windowTop
windowHeight -= windowBottom
......@@ -102,7 +102,13 @@ export function getSystemInfoSync () {
system,
platform,
model,
safeArea
safeArea,
safeAreaInsets: {
top: safeAreaInsets.top,
right: safeAreaInsets.right,
bottom: safeAreaInsets.bottom,
left: safeAreaInsets.left
}
}
}
/**
......
......@@ -50,7 +50,7 @@ export function chooseVideo ({
size: file.size,
duration: 0,
width: 0,
height: 0,
height: 0,
name: file.name
}
......@@ -58,11 +58,20 @@ export function chooseVideo ({
if (video.onloadedmetadata !== undefined) {
// 尝试获取视频的宽高信息
video.onloadedmetadata = function () {
callbackResult.duration = video.duration || 0
callbackResult.width = video.videoWidth || 0
callbackResult.height = video.videoHeight || 0
invoke(callbackId, callbackResult)
invoke(callbackId, Object.assign({}, callbackResult, {
duration: video.duration || 0,
width: video.videoWidth || 0,
height: video.videoHeight || 0
}))
}
// 部分浏览器(如微信内置浏览器)未播放无法触发loadedmetadata事件
setTimeout(() => {
invoke(callbackId, Object.assign({}, callbackResult, {
duration: 0,
width: 0,
height: 0
}))
}, 300)
video.src = filePath
} else {
invoke(callbackId, callbackResult)
......
......@@ -24,11 +24,12 @@ const passiveOptions = supportsPassive ? {
function updateCssVar (vm) {
if (uni.canIUse('css.var')) {
const pageVm = vm.$parent.$parent
const windowTop = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' && pageVm.navigationBar.type !==
'float' ? (NAVBAR_HEIGHT +
'px')
: '0px'
const windowBottom = getApp().$children[0].showTabBar ? (TABBAR_HEIGHT + 'px') : '0px'
const navigationBarType = pageVm.navigationBar.type
const windowTopValue = navigationBarType === 'default' || navigationBarType === 'float' ? NAVBAR_HEIGHT : 0
const windowBottomValue = getApp().$children[0].showTabBar ? TABBAR_HEIGHT : 0
const envMethod = uni.canIUse('css.env') ? 'env' : (uni.canIUse('css.constant') ? 'constant' : '')
const windowTop = windowTopValue && envMethod ? `calc(${windowTopValue}px + ${envMethod}(safe-area-inset-top))` : '0px'
const windowBottom = windowBottomValue && envMethod ? `calc(${windowBottomValue}px + ${envMethod}(safe-area-inset-bottom))` : '0px'
const style = document.documentElement.style
style.setProperty('--window-top', windowTop)
style.setProperty('--window-bottom', windowBottom)
......@@ -37,7 +38,7 @@ function updateCssVar (vm) {
}
}
export default function initSubscribe (subscribe) {
export default function initSubscribe (subscribe) {
let scrollListener = false
let disableScrollListener = false
......@@ -83,5 +84,5 @@ export default function initSubscribe (subscribe) {
document.addEventListener('scroll', scrollListener)
})
}
})
}
})
}
......@@ -498,7 +498,11 @@ export default {
}
} else {
if (document.fullscreenEnabled || document.webkitFullscreenEnabled) {
document[document.fullscreenEnabled ? 'exitFullscreen' : 'webkitExitFullscreen']()
if (document.fullscreenElement) {
document.exitFullscreen()
} else if (document.webkitFullscreenElement) {
document.webkitExitFullscreen()
}
} else if (video.webkitExitFullScreen) {
video.webkitExitFullScreen()
} else {
......
import previewImage from '../../helpers/normalize-preview-image'
function addSafeAreaInsets (result) {
if (result.safeArea) {
const safeArea = result.safeArea
result.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: result.windowWidth - safeArea.right,
bottom: result.windowHeight - safeArea.bottom
}
}
}
export const protocols = {
previewImage
previewImage,
getSystemInfo: {
returnValue: addSafeAreaInsets
},
getSystemInfoSync: {
returnValue: addSafeAreaInsets
}
}
export const todos = [
'vibrate'
export const todos = [
'vibrate'
]
export const canIUses = []
export const canIUses = []
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册