提交 3969441b 编写于 作者: fxy060608's avatar fxy060608

wip(app): uni-app-plus

上级 24cce19a
此差异已折叠。
...@@ -31,10 +31,7 @@ declare namespace UniApp { ...@@ -31,10 +31,7 @@ declare namespace UniApp {
nvue?: { nvue?: {
'flex-direction': 'column' | 'row' 'flex-direction': 'column' | 'row'
} }
globalStyle: { globalStyle: PagesJsonPageStyle & {
navigationBar: PageNavigationBar
pullToRefresh?: PageRefreshOptions
maxWidth?: number
rpxCalcMaxDeviceWidth?: number rpxCalcMaxDeviceWidth?: number
rpxCalcBaseDeviceWidth?: number rpxCalcBaseDeviceWidth?: number
// rpxCalcIncludeWidth?: number // rpxCalcIncludeWidth?: number
...@@ -158,6 +155,10 @@ declare namespace UniApp { ...@@ -158,6 +155,10 @@ declare namespace UniApp {
onReachBottomDistance?: number onReachBottomDistance?: number
pageOrientation?: 'auto' | 'portrait' | 'landscape' pageOrientation?: 'auto' | 'portrait' | 'landscape'
backgroundColor?: string backgroundColor?: string
maxWidth?: string | number
// app-plus
animationType?: string
animationDuration?: number
} }
interface PageRouteMeta extends PagesJsonPageStyle { interface PageRouteMeta extends PagesJsonPageStyle {
id?: number id?: number
...@@ -171,7 +172,6 @@ declare namespace UniApp { ...@@ -171,7 +172,6 @@ declare namespace UniApp {
topWindow?: boolean topWindow?: boolean
leftWindow?: boolean leftWindow?: boolean
rightWindow?: boolean rightWindow?: boolean
maxWidth?: string | number
} }
interface PagesJsonPageOptions { interface PagesJsonPageOptions {
......
...@@ -6588,6 +6588,9 @@ ...@@ -6588,6 +6588,9 @@
}); });
function publishHandler(event, args = {}) { function publishHandler(event, args = {}) {
const pageId = plus.webview.currentWebview().id; const pageId = plus.webview.currentWebview().id;
{
console.log(`[VIEW][${Date.now()}]:`, event, args, pageId);
}
plus.webview.postMessageToUniNView({ plus.webview.postMessageToUniNView({
type: "subscribeHandler", type: "subscribeHandler",
args: { args: {
......
...@@ -102,7 +102,7 @@ export function isTabBarPage(path = '') { ...@@ -102,7 +102,7 @@ export function isTabBarPage(path = '') {
const route = getRouteOptions(path) const route = getRouteOptions(path)
return route && route.meta.isTabBar return route && route.meta.isTabBar
} catch (e) { } catch (e) {
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log('getCurrentPages is not ready') console.log('getCurrentPages is not ready')
} }
} }
......
...@@ -15,7 +15,7 @@ function getLocationSuccess( ...@@ -15,7 +15,7 @@ function getLocationSuccess(
) { ) {
const coords = position.coords const coords = position.coords
if (type !== position.coordsType) { if (type !== position.coordsType) {
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log( console.log(
`UNIAPP[location]:before[${position.coordsType}][lng:${coords.longitude},lat:${coords.latitude}]` `UNIAPP[location]:before[${position.coordsType}][lng:${coords.longitude},lat:${coords.latitude}]`
) )
...@@ -29,7 +29,7 @@ function getLocationSuccess( ...@@ -29,7 +29,7 @@ function getLocationSuccess(
if (coordArray) { if (coordArray) {
coords.longitude = coordArray[0] coords.longitude = coordArray[0]
coords.latitude = coordArray[1] coords.latitude = coordArray[1]
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log( console.log(
`UNIAPP[location]:after[${type}][lng:${coords.longitude},lat:${coords.latitude}]` `UNIAPP[location]:after[${type}][lng:${coords.longitude},lat:${coords.latitude}]`
) )
......
import { parseUrl } from '@dcloudio/uni-shared'
import { getRouteMeta } from '@dcloudio/uni-core'
import { import {
API_NAVIGATE_TO, API_NAVIGATE_TO,
API_TYPE_NAVIGATE_TO, API_TYPE_NAVIGATE_TO,
...@@ -6,9 +8,84 @@ import { ...@@ -6,9 +8,84 @@ import {
NavigateToProtocol, NavigateToProtocol,
} from '@dcloudio/uni-api' } from '@dcloudio/uni-api'
import { ANI_DURATION, ANI_SHOW } from '../../constants'
import { navigate } from './utils'
import { showWebview } from './webview'
import { registerPage } from '../../framework/page'
export const navigateTo = defineAsyncApi<API_TYPE_NAVIGATE_TO>( export const navigateTo = defineAsyncApi<API_TYPE_NAVIGATE_TO>(
API_NAVIGATE_TO, API_NAVIGATE_TO,
({ url }, { resolve, reject }) => {}, (args, { resolve, reject }) => {
const { url, animationType, animationDuration } = args
const { path, query } = parseUrl(url)
const [aniType, aniDuration] = initAnimation(
path,
animationType,
animationDuration
)
navigate(
path,
() => {
_navigateTo({
url,
path,
query,
aniType,
aniDuration,
})
.then(resolve)
.catch(reject)
},
(args as any).openType === 'appLaunch'
)
},
NavigateToProtocol, NavigateToProtocol,
NavigateToOptions NavigateToOptions
) )
interface NavigateToOptions {
url: string
path: string
query: Record<string, any>
aniType: string
aniDuration: number
}
function _navigateTo({
url,
path,
query,
aniType,
aniDuration,
}: NavigateToOptions): Promise<undefined> {
// TODO eventChannel
return new Promise((resolve) => {
showWebview(
registerPage({ url, path, query, openType: 'navigateTo' }),
aniType,
aniDuration,
() => {
resolve(undefined)
}
)
})
}
function initAnimation(
path: string,
animationType?: string,
animationDuration?: number
) {
const { globalStyle } = __uniConfig
const meta = getRouteMeta(path)!
return [
animationType ||
meta.animationType ||
globalStyle.animationType ||
ANI_SHOW,
animationDuration ||
meta.animationDuration ||
globalStyle.animationDuration ||
ANI_DURATION,
] as const
}
...@@ -67,7 +67,7 @@ function pendingNavigate() { ...@@ -67,7 +67,7 @@ function pendingNavigate() {
return return
} }
const { callback } = pendingNavigator const { callback } = pendingNavigator
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log(`pendingNavigate:${pendingNavigator.path}`) console.log(`pendingNavigate:${pendingNavigator.path}`)
} }
pendingNavigator = false pendingNavigator = false
...@@ -86,7 +86,7 @@ export function navigateFinish() { ...@@ -86,7 +86,7 @@ export function navigateFinish() {
} }
// 创建预加载 // 创建预加载
const preloadWebview = createPreloadWebview() const preloadWebview = createPreloadWebview()
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log(`navigateFinish.preloadWebview:${preloadWebview.id}`) console.log(`navigateFinish.preloadWebview:${preloadWebview.id}`)
} }
if (!pendingNavigator) { if (!pendingNavigator) {
......
import { navigateFinish } from './utils'
export function closeWebview(
webview: PlusWebviewWebviewObject,
animationType: string,
animationDuration: number
) {
webview[(webview as any).__preload__ ? 'hide' : 'close'](
animationType as any,
animationDuration
)
}
export function showWebview(
webview: PlusWebviewWebviewObject,
animationType: string,
animationDuration: number,
showCallback: Function,
delay?: number
) {
if (typeof delay === 'undefined') {
delay = (webview as any).nvue ? 0 : 100
}
if (__DEV__) {
console.log(`[show][${Date.now()}]`, delay)
}
const execShowCallback = function () {
if (execShowCallback._called) {
if (__DEV__) {
console.log('execShowCallback.prevent')
}
return
}
execShowCallback._called = true
showCallback && showCallback()
navigateFinish()
}
execShowCallback._called = false
setTimeout(() => {
const timer = setTimeout(() => {
if (__DEV__) {
console.log(`[show.callback.timer][${Date.now()}]`)
}
execShowCallback()
}, animationDuration + 150)
webview.show(animationType as any, animationDuration, () => {
if (__DEV__) {
console.log(`[show.callback][${Date.now()}]`)
}
if (!execShowCallback._called) {
clearTimeout(timer)
}
execShowCallback()
})
}, delay)
}
const downgrade = plus.os.name === 'Android' && parseInt(plus.os.version!) < 6
export const ANI_SHOW = downgrade ? 'slide-in-right' : 'pop-in'
export const ANI_DURATION = 300
export const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'
export const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'
import { hasOwn } from '@vue/shared' import { hasOwn } from '@vue/shared'
import { NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE } from '@dcloudio/uni-shared' import { NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE } from '@dcloudio/uni-shared'
import { initEntry } from '../app/initEntry' import { initEntry } from '../app/initEntry'
import { initRouteOptions } from './initRouteOptions' import { initRouteOptions } from './routeOptions'
import { createWebview } from '../webview' import { createWebview, initWebview } from '../webview'
import { createPage } from './define' import { createPage } from './define'
import { PageNodeOptions } from '../dom/Page' import { PageNodeOptions } from '../dom/Page'
import { getStatusbarHeight } from '../../../helpers/statusBar' import { getStatusbarHeight } from '../../../helpers/statusBar'
...@@ -22,7 +22,7 @@ interface RegisterPageOptions { ...@@ -22,7 +22,7 @@ interface RegisterPageOptions {
query: Record<string, string> query: Record<string, string>
openType: OpenType openType: OpenType
webview?: PlusWebviewWebviewObject webview?: PlusWebviewWebviewObject
eventChannel: unknown // eventChannel: unknown
} }
export function registerPage({ export function registerPage({
...@@ -45,10 +45,19 @@ export function registerPage({ ...@@ -45,10 +45,19 @@ export function registerPage({
webview = plus.webview.getWebviewById(webview.id) webview = plus.webview.getWebviewById(webview.id)
;(webview as any).nvue = routeOptions.meta.isNVue ;(webview as any).nvue = routeOptions.meta.isNVue
} }
routeOptions.meta.id = parseInt(webview.id!)
if (__DEV__) { if (__DEV__) {
console.log(`[uni-app] registerPage(${path},${webview.id})`) console.log(`[uni-app] registerPage(${path},${webview.id})`)
} }
initWebview(webview, path, query, routeOptions.meta)
const route = path.substr(1) const route = path.substr(1)
;(webview as any).__uniapp_route = route
if (!(webview as any).nvue) { if (!(webview as any).nvue) {
createPage( createPage(
parseInt(webview.id!), parseInt(webview.id!),
......
import { getRouteOptions } from '@dcloudio/uni-core' import { getRouteOptions, initRouteMeta } from '@dcloudio/uni-core'
import { OpenType } from '.' import { OpenType } from '.'
export function initRouteOptions(path: string, openType: OpenType) { export function initRouteOptions(path: string, openType: OpenType) {
...@@ -6,6 +6,9 @@ export function initRouteOptions(path: string, openType: OpenType) { ...@@ -6,6 +6,9 @@ export function initRouteOptions(path: string, openType: OpenType) {
const routeOptions = JSON.parse( const routeOptions = JSON.parse(
JSON.stringify(getRouteOptions(path)!) JSON.stringify(getRouteOptions(path)!)
) as UniApp.UniRoute ) as UniApp.UniRoute
routeOptions.meta = initRouteMeta(routeOptions.meta)
if ( if (
openType === 'reLaunch' || openType === 'reLaunch' ||
(!__uniConfig.realEntryPagePath && getCurrentPages().length === 0) // redirectTo (!__uniConfig.realEntryPagePath && getCurrentPages().length === 0) // redirectTo
......
...@@ -2,6 +2,8 @@ import { ON_WEBVIEW_READY } from '../../../constants' ...@@ -2,6 +2,8 @@ import { ON_WEBVIEW_READY } from '../../../constants'
import { createNVueWebview } from './nvue' import { createNVueWebview } from './nvue'
import { getPreloadWebview, getWebviewId } from './utils' import { getPreloadWebview, getWebviewId } from './utils'
export * from './init'
export * from './preload' export * from './preload'
export interface CreateWebviewOptions { export interface CreateWebviewOptions {
......
export function onWebviewClose(webview: PlusWebviewWebviewObject) {
const { popupSubNVueWebviews } = webview as any
if (!popupSubNVueWebviews) {
return
}
webview.addEventListener('close', () => {
Object.keys(popupSubNVueWebviews).forEach((id) => {
if (__DEV__) {
console.log(
`UNIAPP[webview][${webview.id}]:popupSubNVueWebview[${id}].close`
)
}
popupSubNVueWebviews[id].close('none')
})
})
}
import { onWebviewClose } from './close'
import { onWebviewResize } from './resize'
const WEBVIEW_LISTENERS = {
pullToRefresh: 'onPullDownRefresh',
titleNViewSearchInputChanged: 'onNavigationBarSearchInputChanged',
titleNViewSearchInputConfirmed: 'onNavigationBarSearchInputConfirmed',
titleNViewSearchInputClicked: 'onNavigationBarSearchInputClicked',
titleNViewSearchInputFocusChanged: 'onNavigationBarSearchInputFocusChanged',
} as const
export function initWebviewEvent(webview: PlusWebviewWebviewObject) {
const { emit } = UniServiceJSBridge
const id = parseInt(webview.id!)
Object.keys(WEBVIEW_LISTENERS).forEach((name) => {
webview.addEventListener(name as any, (e) => {
emit(WEBVIEW_LISTENERS[name as keyof typeof WEBVIEW_LISTENERS], e, id)
})
})
onWebviewClose(webview)
onWebviewResize(webview)
// TODO
// if (plus.os.name === 'iOS') {
// !(webview as any).nvue && onWebviewRecovery(webview, routeOptions)
// onWebviewPopGesture(webview)
// }
}
import { debounce } from '@dcloudio/uni-shared'
export function onWebviewResize(webview: PlusWebviewWebviewObject) {
const onResize = function ({
width,
height,
}: {
width: number
height: number
}) {
const landscape = Math.abs(plus.navigator.getOrientation()) === 90
const res = {
deviceOrientation: landscape ? 'landscape' : 'portrait',
size: {
windowWidth: Math.ceil(width),
windowHeight: Math.ceil(height),
},
}
UniServiceJSBridge.emit('onViewDidResize', res) // API
UniServiceJSBridge.emit('onResize', res, parseInt(webview.id!)) // Page lifecycle
}
webview.addEventListener('resize' as any, debounce(onResize, 50))
}
import { initWebviewStyle } from './style'
import { initSubNVues } from './subNVues'
export function initWebview(
webview: PlusWebviewWebviewObject,
path: string,
query: Record<string, any>,
routeMeta: UniApp.PageRouteMeta
) {
// 首页或非 nvue 页面
if (webview.id === '1' || !routeMeta.isNVue) {
initWebviewStyle(webview, path, query, routeMeta)
}
initSubNVues(webview, path, routeMeta)
}
import { parseWebviewStyle } from '../style'
import { initUniPageUrl, initDebugRefresh } from '../utils'
export function initWebviewStyle(
webview: PlusWebviewWebviewObject,
path: string,
query: Record<string, any>,
routeMeta: UniApp.PageRouteMeta
) {
const webviewStyle = parseWebviewStyle(path, routeMeta)
webviewStyle.uniPageUrl = initUniPageUrl(path, query)
const isTabBar = !!routeMeta.isTabBar
if (!routeMeta.isNVue) {
webviewStyle.debugRefresh = initDebugRefresh(isTabBar, path, query)
} else {
// android 需要使用
webviewStyle.isTab = isTabBar
}
if (__DEV__) {
console.log('[uni-app] updateWebview', webviewStyle)
}
webview.setStyle(webviewStyle)
}
export function initSubNVues(
webview: PlusWebviewWebviewObject,
path: string,
routeMeta: UniApp.PageRouteMeta
) {}
...@@ -11,7 +11,7 @@ export function createNVueWebview({ ...@@ -11,7 +11,7 @@ export function createNVueWebview({
webviewStyle, webviewStyle,
}: CreateWebviewOptions) { }: CreateWebviewOptions) {
const curWebviewId = genWebviewId() const curWebviewId = genWebviewId()
const curWebviewStyle = parseWebviewStyle(curWebviewId, path, routeOptions) const curWebviewStyle = parseWebviewStyle(path, routeOptions.meta)
;(curWebviewStyle as any).uniPageUrl = initUniPageUrl(path, query) ;(curWebviewStyle as any).uniPageUrl = initUniPageUrl(path, query)
if (__DEV__) { if (__DEV__) {
console.log('[uni-app] createWebview', curWebviewId, path, curWebviewStyle) console.log('[uni-app] createWebview', curWebviewId, path, curWebviewStyle)
......
import { VIEW_WEBVIEW_PATH } from '../constants' import { VIEW_WEBVIEW_PATH } from '../../constants'
import { genWebviewId } from './utils' import { genWebviewId } from './utils'
export let preloadWebview: PlusWebviewWebviewObject & { export let preloadWebview: PlusWebviewWebviewObject & {
......
import { mergePageMeta } from '@dcloudio/uni-core'
import { initNVue } from './nvue' import { initNVue } from './nvue'
import { initBackgroundColor } from './backgroundColor' import { initBackgroundColor } from './backgroundColor'
import { initPopGesture } from './popGesture' import { initPopGesture } from './popGesture'
import { initPullToRefresh } from './pullToRefresh' import { initPullToRefresh } from './pullToRefresh'
import { initTitleNView } from './titleNView' import { initTitleNView } from './titleNView'
import { DebugRefresh, InitUniPageUrl } from '../utils'
export function parseWebviewStyle( export function parseWebviewStyle(
id: number,
path: string, path: string,
routeOptions: UniApp.UniRoute routeMeta: UniApp.PageRouteMeta
): PlusWebviewWebviewStyles { ): PlusWebviewWebviewStyles & {
uniPageUrl?: InitUniPageUrl
debugRefresh?: DebugRefresh
isTab?: boolean
} {
const webviewStyle: PlusWebviewWebviewStyles = { const webviewStyle: PlusWebviewWebviewStyles = {
bounce: 'vertical', bounce: 'vertical',
} }
const routeMeta = mergePageMeta(id, routeOptions.meta)
Object.keys(routeMeta).forEach((name) => { Object.keys(routeMeta).forEach((name) => {
if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) { if (WEBVIEW_STYLE_BLACKLIST.indexOf(name) === -1) {
......
...@@ -19,10 +19,28 @@ function encode(val: Parameters<typeof encodeURIComponent>[0]) { ...@@ -19,10 +19,28 @@ function encode(val: Parameters<typeof encodeURIComponent>[0]) {
return val as string return val as string
} }
export function initUniPageUrl(path: string, query: Record<string, string>) { export type InitUniPageUrl = ReturnType<typeof initUniPageUrl>
export type DebugRefresh = ReturnType<typeof initDebugRefresh>
export function initUniPageUrl(path: string, query: Record<string, any>) {
const queryString = query ? stringifyQuery(query, encode) : '' const queryString = query ? stringifyQuery(query, encode) : ''
return { return {
path: path.substr(1), path: path.substr(1),
query: queryString ? queryString.substr(1) : queryString, query: queryString ? queryString.substr(1) : queryString,
} }
} }
export function initDebugRefresh(
isTab: boolean,
path: string,
query: Record<string, any>
) {
const queryString = query ? stringifyQuery(query, encode) : ''
return {
isTab,
arguments: JSON.stringify({
path: path.substr(1),
query: queryString ? queryString.substr(1) : queryString,
}),
}
}
...@@ -10,7 +10,7 @@ export const UniViewJSBridge = /*#__PURE__*/ extend(ViewJSBridge, { ...@@ -10,7 +10,7 @@ export const UniViewJSBridge = /*#__PURE__*/ extend(ViewJSBridge, {
function publishHandler(event: string, args: unknown = {}) { function publishHandler(event: string, args: unknown = {}) {
const pageId = plus.webview.currentWebview().id const pageId = plus.webview.currentWebview().id
if (process.env.NODE_ENV !== 'production') { if (__DEV__) {
console.log(`[VIEW][${Date.now()}]:`, event, args, pageId) console.log(`[VIEW][${Date.now()}]:`, event, args, pageId)
} }
;(plus.webview as any).postMessageToUniNView( ;(plus.webview as any).postMessageToUniNView(
......
export const jsContext = { export const jsContext = {
VUE3: true,
APP_PLUS: false, APP_PLUS: false,
H5: true, H5: true,
MP_360: false, MP_360: false,
...@@ -18,6 +19,7 @@ export const jsContext = { ...@@ -18,6 +19,7 @@ export const jsContext = {
APP_NVUE: false, APP_NVUE: false,
} }
export const htmlContext = { export const htmlContext = {
VUE3: true,
APP_PLUS: false, APP_PLUS: false,
H5: true, H5: true,
MP_360: false, MP_360: false,
......
...@@ -22,9 +22,9 @@ function initGlobalStyle() { ...@@ -22,9 +22,9 @@ function initGlobalStyle() {
return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})) return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {}))
} }
export function mergePageMeta( export function initRouteMeta(
id: number, pageMeta: UniApp.PageRouteMeta,
pageMeta: UniApp.PageRouteMeta id?: number
): UniApp.PageRouteMeta { ): UniApp.PageRouteMeta {
const globalStyle = initGlobalStyle() const globalStyle = initGlobalStyle()
const res = extend({ id }, globalStyle, pageMeta) const res = extend({ id }, globalStyle, pageMeta)
......
...@@ -429,7 +429,7 @@ const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"]; ...@@ -429,7 +429,7 @@ const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"];
function initGlobalStyle() { function initGlobalStyle() {
return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {}));
} }
function mergePageMeta(id, pageMeta) { function initRouteMeta(pageMeta, id) {
const globalStyle = initGlobalStyle(); const globalStyle = initGlobalStyle();
const res = shared.extend({ id }, globalStyle, pageMeta); const res = shared.extend({ id }, globalStyle, pageMeta);
PAGE_META_KEYS.forEach((name) => { PAGE_META_KEYS.forEach((name) => {
...@@ -6546,9 +6546,9 @@ function usePageRoute() { ...@@ -6546,9 +6546,9 @@ function usePageRoute() {
} }
function initPageMeta(id) { function initPageMeta(id) {
if (__UNI_FEATURE_PAGES__) { if (__UNI_FEATURE_PAGES__) {
return vue.reactive(normalizePageMeta(JSON.parse(JSON.stringify(mergePageMeta(id, vueRouter.useRoute().meta))))); return vue.reactive(normalizePageMeta(JSON.parse(JSON.stringify(initRouteMeta(vueRouter.useRoute().meta, id)))));
} }
return vue.reactive(normalizePageMeta(JSON.parse(JSON.stringify(mergePageMeta(id, __uniRoutes[0].meta))))); return vue.reactive(normalizePageMeta(JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id)))));
} }
function normalizePageMeta(pageMeta) { function normalizePageMeta(pageMeta) {
if (__UNI_FEATURE_PULL_DOWN_REFRESH__) { if (__UNI_FEATURE_PULL_DOWN_REFRESH__) {
...@@ -9565,7 +9565,7 @@ function setNavigationBar(pageMeta, type, args, resolve, reject) { ...@@ -9565,7 +9565,7 @@ function setNavigationBar(pageMeta, type, args, resolve, reject) {
const { frontColor, backgroundColor, animation: animation2 } = args; const { frontColor, backgroundColor, animation: animation2 } = args;
const { duration, timingFunc } = animation2; const { duration, timingFunc } = animation2;
if (frontColor) { if (frontColor) {
navigationBar.titleColor = frontColor === "#000000" ? "#000" : "#fff"; navigationBar.titleColor = frontColor === "#000000" ? "#000000" : "#ffffff";
} }
if (backgroundColor) { if (backgroundColor) {
navigationBar.backgroundColor = backgroundColor; navigationBar.backgroundColor = backgroundColor;
......
...@@ -816,7 +816,7 @@ const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"]; ...@@ -816,7 +816,7 @@ const PAGE_META_KEYS = ["navigationBar", "pullToRefresh"];
function initGlobalStyle() { function initGlobalStyle() {
return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {})); return JSON.parse(JSON.stringify(__uniConfig.globalStyle || {}));
} }
function mergePageMeta(id2, pageMeta) { function initRouteMeta(pageMeta, id2) {
const globalStyle = initGlobalStyle(); const globalStyle = initGlobalStyle();
const res = extend({ id: id2 }, globalStyle, pageMeta); const res = extend({ id: id2 }, globalStyle, pageMeta);
PAGE_META_KEYS.forEach((name) => { PAGE_META_KEYS.forEach((name) => {
...@@ -13026,9 +13026,9 @@ function usePageRoute() { ...@@ -13026,9 +13026,9 @@ function usePageRoute() {
} }
function initPageMeta(id2) { function initPageMeta(id2) {
if (__UNI_FEATURE_PAGES__) { if (__UNI_FEATURE_PAGES__) {
return reactive(normalizePageMeta(JSON.parse(JSON.stringify(mergePageMeta(id2, useRoute().meta))))); return reactive(normalizePageMeta(JSON.parse(JSON.stringify(initRouteMeta(useRoute().meta, id2)))));
} }
return reactive(normalizePageMeta(JSON.parse(JSON.stringify(mergePageMeta(id2, __uniRoutes[0].meta))))); return reactive(normalizePageMeta(JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id2)))));
} }
function normalizePageMeta(pageMeta) { function normalizePageMeta(pageMeta) {
if (__UNI_FEATURE_PULL_DOWN_REFRESH__) { if (__UNI_FEATURE_PULL_DOWN_REFRESH__) {
...@@ -17917,7 +17917,7 @@ function setNavigationBar(pageMeta, type, args, resolve, reject) { ...@@ -17917,7 +17917,7 @@ function setNavigationBar(pageMeta, type, args, resolve, reject) {
const { frontColor, backgroundColor, animation: animation2 } = args; const { frontColor, backgroundColor, animation: animation2 } = args;
const { duration, timingFunc } = animation2; const { duration, timingFunc } = animation2;
if (frontColor) { if (frontColor) {
navigationBar.titleColor = frontColor === "#000000" ? "#000" : "#fff"; navigationBar.titleColor = frontColor === "#000000" ? "#000000" : "#ffffff";
} }
if (backgroundColor) { if (backgroundColor) {
navigationBar.backgroundColor = backgroundColor; navigationBar.backgroundColor = backgroundColor;
......
...@@ -28,7 +28,7 @@ const scrollBehavior: RouterOptions['scrollBehavior'] = ( ...@@ -28,7 +28,7 @@ const scrollBehavior: RouterOptions['scrollBehavior'] = (
function createRouterOptions(): RouterOptions { function createRouterOptions(): RouterOptions {
return { return {
history: initHistory(), history: initHistory(),
strict: !!__uniConfig.router.strict, strict: !!__uniConfig.router!.strict,
routes: __uniRoutes as unknown as RouteRecordRaw[], routes: __uniRoutes as unknown as RouteRecordRaw[],
scrollBehavior, scrollBehavior,
} }
...@@ -45,7 +45,7 @@ function removeCurrentPages(delta: number = 1) { ...@@ -45,7 +45,7 @@ function removeCurrentPages(delta: number = 1) {
} }
function initHistory() { function initHistory() {
let { base } = __uniConfig.router let { base } = __uniConfig.router!
if (base === '/') { if (base === '/') {
base = '' base = ''
} }
......
...@@ -4,7 +4,7 @@ import { useRoute } from 'vue-router' ...@@ -4,7 +4,7 @@ import { useRoute } from 'vue-router'
import { NAVBAR_HEIGHT, parseQuery } from '@dcloudio/uni-shared' import { NAVBAR_HEIGHT, parseQuery } from '@dcloudio/uni-shared'
import { import {
mergePageMeta, initRouteMeta,
normalizePullToRefreshRpx, normalizePullToRefreshRpx,
PolySymbol, PolySymbol,
} from '@dcloudio/uni-core' } from '@dcloudio/uni-core'
...@@ -48,9 +48,9 @@ function initPageMeta(id: number) { ...@@ -48,9 +48,9 @@ function initPageMeta(id: number) {
normalizePageMeta( normalizePageMeta(
JSON.parse( JSON.parse(
JSON.stringify( JSON.stringify(
mergePageMeta( initRouteMeta(
id, useRoute().meta as unknown as UniApp.PageRouteMeta,
useRoute().meta as unknown as UniApp.PageRouteMeta id
) )
) )
) )
...@@ -59,7 +59,7 @@ function initPageMeta(id: number) { ...@@ -59,7 +59,7 @@ function initPageMeta(id: number) {
} }
return reactive<UniApp.PageRouteMeta>( return reactive<UniApp.PageRouteMeta>(
normalizePageMeta( normalizePageMeta(
JSON.parse(JSON.stringify(mergePageMeta(id, __uniRoutes[0].meta))) JSON.parse(JSON.stringify(initRouteMeta(__uniRoutes[0].meta, id)))
) )
) )
} }
...@@ -83,7 +83,7 @@ function normalizePageMeta(pageMeta: UniApp.PageRouteMeta) { ...@@ -83,7 +83,7 @@ function normalizePageMeta(pageMeta: UniApp.PageRouteMeta) {
) )
const { type, style } = navigationBar const { type, style } = navigationBar
if (style !== 'custom' && type !== 'transparent') { if (style !== 'custom' && type !== 'transparent') {
pullToRefresh.offset += pullToRefresh.offset! +=
NAVBAR_HEIGHT + (__NODE_JS__ ? 0 : safeAreaInsets.top) NAVBAR_HEIGHT + (__NODE_JS__ ? 0 : safeAreaInsets.top)
} }
pageMeta.pullToRefresh = pullToRefresh pageMeta.pullToRefresh = pullToRefresh
......
...@@ -32,7 +32,8 @@ function setNavigationBar( ...@@ -32,7 +32,8 @@ function setNavigationBar(
const { frontColor, backgroundColor, animation } = args const { frontColor, backgroundColor, animation } = args
const { duration, timingFunc } = animation const { duration, timingFunc } = animation
if (frontColor) { if (frontColor) {
navigationBar.titleColor = frontColor === '#000000' ? '#000' : '#fff' navigationBar.titleColor =
frontColor === '#000000' ? '#000000' : '#ffffff'
} }
if (backgroundColor) { if (backgroundColor) {
navigationBar.backgroundColor = backgroundColor navigationBar.backgroundColor = backgroundColor
......
...@@ -130,6 +130,97 @@ function scrollTo(scrollTop, duration) { ...@@ -130,6 +130,97 @@ function scrollTo(scrollTop, duration) {
scrollTo(duration); scrollTo(duration);
} }
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (shared.isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
/**
* Decode text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @param text - string to decode
* @returns decoded string
*/
function decode(text) {
try {
return decodeURIComponent('' + text);
}
catch (err) { }
return '' + text;
}
function decodedQuery(query = {}) {
const decodedQuery = {};
Object.keys(query).forEach((name) => {
try {
decodedQuery[name] = decode(query[name]);
}
catch (e) {
decodedQuery[name] = query[name];
}
});
return decodedQuery;
}
const PLUS_RE = /\+/g; // %2B
/**
* https://github.com/vuejs/vue-router-next/blob/master/src/query.ts
* @internal
*
* @param search - search string to parse
* @returns a query object
*/
function parseQuery(search) {
const query = {};
// avoid creating an object with an empty key and empty value
// because of split('&')
if (search === '' || search === '?')
return query;
const hasLeadingIM = search[0] === '?';
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
for (let i = 0; i < searchParams.length; ++i) {
// pre decode the + into space
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
// allow the = character
let eqPos = searchParam.indexOf('=');
let key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
let value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
if (key in query) {
// an extra variable for ts types
let currentValue = query[key];
if (!shared.isArray(currentValue)) {
currentValue = query[key] = [currentValue];
}
currentValue.push(value);
}
else {
query[key] = value;
}
}
return query;
}
function parseUrl(url) {
const [path, querystring] = url.split('?', 2);
return {
path,
query: parseQuery(querystring),
};
}
function plusReady(callback) { function plusReady(callback) {
if (typeof callback !== 'function') { if (typeof callback !== 'function') {
return; return;
...@@ -769,89 +860,6 @@ function callOptions(options, data) { ...@@ -769,89 +860,6 @@ function callOptions(options, data) {
} }
} }
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (shared.isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
/**
* Decode text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @param text - string to decode
* @returns decoded string
*/
function decode(text) {
try {
return decodeURIComponent('' + text);
}
catch (err) { }
return '' + text;
}
function decodedQuery(query = {}) {
const decodedQuery = {};
Object.keys(query).forEach((name) => {
try {
decodedQuery[name] = decode(query[name]);
}
catch (e) {
decodedQuery[name] = query[name];
}
});
return decodedQuery;
}
const PLUS_RE = /\+/g; // %2B
/**
* https://github.com/vuejs/vue-router-next/blob/master/src/query.ts
* @internal
*
* @param search - search string to parse
* @returns a query object
*/
function parseQuery(search) {
const query = {};
// avoid creating an object with an empty key and empty value
// because of split('&')
if (search === '' || search === '?')
return query;
const hasLeadingIM = search[0] === '?';
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
for (let i = 0; i < searchParams.length; ++i) {
// pre decode the + into space
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
// allow the = character
let eqPos = searchParam.indexOf('=');
let key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
let value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
if (key in query) {
// an extra variable for ts types
let currentValue = query[key];
if (!shared.isArray(currentValue)) {
currentValue = query[key] = [currentValue];
}
currentValue.push(value);
}
else {
query[key] = value;
}
}
return query;
}
function debounce(fn, delay) { function debounce(fn, delay) {
let timeout; let timeout;
const newFn = function () { const newFn = function () {
...@@ -949,6 +957,7 @@ exports.normalizeDataset = normalizeDataset; ...@@ -949,6 +957,7 @@ exports.normalizeDataset = normalizeDataset;
exports.normalizeTarget = normalizeTarget; exports.normalizeTarget = normalizeTarget;
exports.once = once; exports.once = once;
exports.parseQuery = parseQuery; exports.parseQuery = parseQuery;
exports.parseUrl = parseUrl;
exports.passive = passive; exports.passive = passive;
exports.plusReady = plusReady; exports.plusReady = plusReady;
exports.removeLeadingSlash = removeLeadingSlash; exports.removeLeadingSlash = removeLeadingSlash;
......
...@@ -138,6 +138,11 @@ declare interface Options { ...@@ -138,6 +138,11 @@ declare interface Options {
*/ */
export declare function parseQuery(search: string): Record<string, any>; export declare function parseQuery(search: string): Record<string, any>;
export declare function parseUrl(url: string): {
path: string;
query: Record<string, any>;
};
export declare function passive(passive: boolean): { export declare function passive(passive: boolean): {
passive: boolean; passive: boolean;
}; };
......
import { camelize, extend, isString, isHTMLTag, isSVGTag, capitalize, isPlainObject, isArray } from '@vue/shared'; import { camelize, extend, isString, isPlainObject, isArray, isHTMLTag, isSVGTag, capitalize } from '@vue/shared';
function formatKey(key) { function formatKey(key) {
return camelize(key.substring(5)); return camelize(key.substring(5));
...@@ -126,6 +126,97 @@ function scrollTo(scrollTop, duration) { ...@@ -126,6 +126,97 @@ function scrollTo(scrollTop, duration) {
scrollTo(duration); scrollTo(duration);
} }
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
/**
* Decode text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @param text - string to decode
* @returns decoded string
*/
function decode(text) {
try {
return decodeURIComponent('' + text);
}
catch (err) { }
return '' + text;
}
function decodedQuery(query = {}) {
const decodedQuery = {};
Object.keys(query).forEach((name) => {
try {
decodedQuery[name] = decode(query[name]);
}
catch (e) {
decodedQuery[name] = query[name];
}
});
return decodedQuery;
}
const PLUS_RE = /\+/g; // %2B
/**
* https://github.com/vuejs/vue-router-next/blob/master/src/query.ts
* @internal
*
* @param search - search string to parse
* @returns a query object
*/
function parseQuery(search) {
const query = {};
// avoid creating an object with an empty key and empty value
// because of split('&')
if (search === '' || search === '?')
return query;
const hasLeadingIM = search[0] === '?';
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
for (let i = 0; i < searchParams.length; ++i) {
// pre decode the + into space
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
// allow the = character
let eqPos = searchParam.indexOf('=');
let key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
let value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
if (key in query) {
// an extra variable for ts types
let currentValue = query[key];
if (!isArray(currentValue)) {
currentValue = query[key] = [currentValue];
}
currentValue.push(value);
}
else {
query[key] = value;
}
}
return query;
}
function parseUrl(url) {
const [path, querystring] = url.split('?', 2);
return {
path,
query: parseQuery(querystring),
};
}
function plusReady(callback) { function plusReady(callback) {
if (typeof callback !== 'function') { if (typeof callback !== 'function') {
return; return;
...@@ -765,89 +856,6 @@ function callOptions(options, data) { ...@@ -765,89 +856,6 @@ function callOptions(options, data) {
} }
} }
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
const res = obj
? Object.keys(obj)
.map((key) => {
let val = obj[key];
if (typeof val === undefined || val === null) {
val = '';
}
else if (isPlainObject(val)) {
val = JSON.stringify(val);
}
return encodeStr(key) + '=' + encodeStr(val);
})
.filter((x) => x.length > 0)
.join('&')
: null;
return res ? `?${res}` : '';
}
/**
* Decode text using `decodeURIComponent`. Returns the original text if it
* fails.
*
* @param text - string to decode
* @returns decoded string
*/
function decode(text) {
try {
return decodeURIComponent('' + text);
}
catch (err) { }
return '' + text;
}
function decodedQuery(query = {}) {
const decodedQuery = {};
Object.keys(query).forEach((name) => {
try {
decodedQuery[name] = decode(query[name]);
}
catch (e) {
decodedQuery[name] = query[name];
}
});
return decodedQuery;
}
const PLUS_RE = /\+/g; // %2B
/**
* https://github.com/vuejs/vue-router-next/blob/master/src/query.ts
* @internal
*
* @param search - search string to parse
* @returns a query object
*/
function parseQuery(search) {
const query = {};
// avoid creating an object with an empty key and empty value
// because of split('&')
if (search === '' || search === '?')
return query;
const hasLeadingIM = search[0] === '?';
const searchParams = (hasLeadingIM ? search.slice(1) : search).split('&');
for (let i = 0; i < searchParams.length; ++i) {
// pre decode the + into space
const searchParam = searchParams[i].replace(PLUS_RE, ' ');
// allow the = character
let eqPos = searchParam.indexOf('=');
let key = decode(eqPos < 0 ? searchParam : searchParam.slice(0, eqPos));
let value = eqPos < 0 ? null : decode(searchParam.slice(eqPos + 1));
if (key in query) {
// an extra variable for ts types
let currentValue = query[key];
if (!isArray(currentValue)) {
currentValue = query[key] = [currentValue];
}
currentValue.push(value);
}
else {
query[key] = value;
}
}
return query;
}
function debounce(fn, delay) { function debounce(fn, delay) {
let timeout; let timeout;
const newFn = function () { const newFn = function () {
...@@ -884,4 +892,4 @@ function getEnvLocale() { ...@@ -884,4 +892,4 @@ function getEnvLocale() {
return (lang && lang.replace(/[.:].*/, '')) || 'en'; return (lang && lang.replace(/[.:].*/, '')) || 'en';
} }
export { BACKGROUND_COLOR, BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, addFont, cache, cacheStringFunction, callOptions, createRpx2Unit, debounce, decode, decodeAttr, decodeTag, decodedQuery, defaultRpx2Unit, encodeAttr, encodeTag, formatDateTime, getCustomDataset, getEnvLocale, getLen, initCustomDataset, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, isServiceCustomElement, isServiceNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, sanitise, scrollTo, stringifyQuery, updateElementStyle }; export { BACKGROUND_COLOR, BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, DATA_RE, NAVBAR_HEIGHT, NODE_TYPE_COMMENT, NODE_TYPE_ELEMENT, NODE_TYPE_PAGE, NODE_TYPE_TEXT, ON_REACH_BOTTOM_DISTANCE, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, SCHEME_RE, SELECTED_COLOR, TABBAR_HEIGHT, TAGS, UNI_SSR, UNI_SSR_DATA, UNI_SSR_GLOBAL_DATA, UNI_SSR_STORE, UNI_SSR_TITLE, UniBaseNode, UniCommentNode, UniElement, UniEvent, UniInputElement, UniNode, UniTextAreaElement, UniTextNode, WEB_INVOKE_APPSERVICE, addFont, cache, cacheStringFunction, callOptions, createRpx2Unit, debounce, decode, decodeAttr, decodeTag, decodedQuery, defaultRpx2Unit, encodeAttr, encodeTag, formatDateTime, getCustomDataset, getEnvLocale, getLen, initCustomDataset, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, isServiceCustomElement, isServiceNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, parseUrl, passive, plusReady, removeLeadingSlash, sanitise, scrollTo, stringifyQuery, updateElementStyle };
export * from './dom' export * from './dom'
export * from './url'
export * from './plus' export * from './plus'
export * from './tags' export * from './tags'
export * from './vdom' export * from './vdom'
......
import { parseQuery } from './query'
export function parseUrl(url: string) {
const [path, querystring] = url.split('?', 2)
return {
path,
query: parseQuery(querystring),
}
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册