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

wip(app): uni-app-plus

上级 dbb3d133
......@@ -7,6 +7,8 @@ declare namespace Page {
fullPath: string
options: Record<string, any>
meta: UniApp.PageRouteMeta
openType: UniApp.OpenType
statusBarStyle?: string
}
}
}
......@@ -14,6 +16,14 @@ declare namespace UniApp {
type ClassObj = Record<string, boolean>
type StyleObj = Record<string, any>
type PLATFORM = keyof PagesJsonPagePlatformStyle
type OpenType =
| 'navigateTo'
| 'redirectTo'
| 'reLaunch'
| 'switchTab'
| 'navigateBack'
| 'preloadPage'
interface LayoutWindowOptions {
matchMedia?: {
minWidth?: number
......
......@@ -5,6 +5,8 @@ declare module '@vue/runtime-core' {
$scope: {
$getAppWebview?: () => PlusWebviewWebviewObject
}
// 目前 H5,APP 平台 getCurrentPages 中获取的 page 对象调整为 vm 对象
$getAppWebview?: () => PlusWebviewWebviewObject
$page: Page.PageInstance['$page']
__isTabBar: boolean
}
......
......@@ -130,6 +130,14 @@ function wrapperOffApi<T extends ApiLike>(
}
}
function normalizeErrMsg(errMsg: string | Error) {
if (errMsg instanceof Error) {
console.error(errMsg)
return errMsg.message
}
return errMsg
}
function wrapperTaskApi<T extends ApiLike>(
name: string,
fn: Function,
......@@ -144,8 +152,8 @@ function wrapperTaskApi<T extends ApiLike>(
}
return fn(args, {
resolve: (res: unknown) => invokeSuccess(id, name, res),
reject: (errMsg: string, errRes?: any) =>
invokeFail(id, name, errMsg, errRes),
reject: (errMsg: string | Error, errRes?: any) =>
invokeFail(id, name, normalizeErrMsg(errMsg), errRes),
})
}
}
......
import { UniNodeJSON } from '@dcloudio/uni-shared'
import { UniEventListener, UniNodeJSON } from '@dcloudio/uni-shared'
import { createPageNode } from '../../../src/service/framework/dom/Page'
import {
createElement,
createTextNode,
withModifiers,
} from '../../../../uni-app-vue/lib/service.runtime.esm'
import {
InsertAction,
......@@ -13,6 +14,8 @@ import {
ACTION_TYPE_SET_TEXT,
ACTION_TYPE_REMOVE,
} from '../../../src/PageAction'
import { EventModifierFlags } from '@dcloudio/uni-shared'
describe('dom', () => {
const pageId = 1
const root = createPageNode(pageId, {
......@@ -96,7 +99,7 @@ describe('dom', () => {
expect(addEventListenerAction[0]).toBe(ACTION_TYPE_SET_ATTRIBUTE)
expect(addEventListenerAction[1]).toBe(2)
expect(addEventListenerAction[2]).toBe('.e0')
expect(addEventListenerAction[3]).toBe(1)
expect(addEventListenerAction[3]).toBe(0)
root.updateActions.length = 0
textNode.removeEventListener('click', clickFn)
......@@ -106,5 +109,22 @@ describe('dom', () => {
expect(removeEventListenerAction[0]).toBe(ACTION_TYPE_REMOVE_ATTRIBUTE)
expect(removeEventListenerAction[1]).toBe(2)
expect(removeEventListenerAction[2]).toBe('.e0')
root.updateActions.length = 0
const clickFn1 = withModifiers(() => {}, [
'stop',
'prevent',
]) as unknown as UniEventListener
textNode.addEventListener('click', clickFn1, { capture: true })
const {
updateActions: [addEventListenerAction1],
} = root
expect(addEventListenerAction1[0]).toBe(ACTION_TYPE_SET_ATTRIBUTE)
expect(addEventListenerAction1[1]).toBe(2)
expect(addEventListenerAction1[2]).toBe('.e00')
const flag = addEventListenerAction1[3] as number
expect(flag & EventModifierFlags.stop).toBeTruthy()
expect(flag & EventModifierFlags.prevent).toBeTruthy()
expect(flag & EventModifierFlags.self).toBeFalsy()
})
})
import { compileTemplate } from '@vue/compiler-sfc'
import { UniAppPlugin } from '../../../uni-app-vite/src/plugin'
import {
ref,
nextTick,
......@@ -6,6 +9,7 @@ import {
openBlock as _openBlock,
createBlock as _createBlock,
createCommentVNode as _createCommentVNode,
withModifiers as _withModifiers,
} from '../../../uni-app-vue/lib/service.runtime.esm'
import { createPageNode } from '../../src/service/framework/dom/Page'
......@@ -23,10 +27,31 @@ const defaultPageNodeOptions = {
windowTop: 0,
windowBottom: 0,
}
const { uni } = UniAppPlugin
function compile(source: string) {
return compileTemplate({
source,
filename: 'demo',
id: 'test',
compilerOptions: { mode: 'module', ...uni!.compilerOptions },
}).code
}
console.log(
compile(
`<view class="a" @click.stop="handleClick"><view v-if="show" style="color:red">123</view></view>`
)
)
describe('vue', () => {
test('vdom', () => {
const show = ref(true)
let handleClick: Function | null = () => {}
let handleClick: Function | null = _withModifiers(() => {}, [
'stop',
'self',
])
const Page = {
setup() {
return () => {
......@@ -34,7 +59,10 @@ describe('vue', () => {
_openBlock(),
_createBlock(
'view',
{ class: 'a', onClick: handleClick },
{
class: 'a',
onClickPassiveCaptureOnce: handleClick,
},
[
show.value
? (_openBlock(),
......@@ -49,7 +77,7 @@ describe('vue', () => {
: _createCommentVNode('v-if', true),
],
8 /* PROPS */,
['onClick']
['onClickPassiveCaptureOnce']
)
)
}
......
......@@ -12,6 +12,7 @@
}
},
"replacements": {
"__PLATFORM__": "'app'",
"__VUE_OPTIONS_API__": "true",
"__VUE_PROD_DEVTOOLS__": "false",
"__UNI_FEATURE_WX__": "true",
......
......@@ -833,6 +833,20 @@
offsetLeft
};
}
function normalizeEventType(type, options) {
if (options) {
if (options.capture) {
type += "Capture";
}
if (options.once) {
type += "Once";
}
if (options.passive) {
type += "Passive";
}
}
return `on${capitalize(camelize(type))}`;
}
const optionsModifierRE$1 = /(?:Once|Passive|Capture)$/;
function parseEventName(name) {
let options;
......@@ -846,9 +860,12 @@
}
return [hyphenate(name.slice(2)), options];
}
const ATTR_MAP = {
class: ".c",
style: ".s",
const EventModifierFlags = {
stop: 1,
prevent: 1 << 1,
self: 1 << 2
};
const EVENT_MAP = {
onClick: ".e0",
onChange: ".e1",
onInput: ".e2",
......@@ -865,10 +882,33 @@
onAnimationend: ".ed",
onTouchforcechange: ".ee"
};
const DECODED_ATTR_MAP = /* @__PURE__ */ Object.keys(ATTR_MAP).reduce((map, name) => {
map[ATTR_MAP[name]] = name;
return map;
}, Object.create(null));
const OPTIONS = [
"Capture",
"CaptureOnce",
"CapturePassive",
"CaptureOncePassive",
"Once",
"OncePassive",
"Passive"
];
const ATTR_MAP = /* @__PURE__ */ extend({
class: ".c",
style: ".s"
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function decodeObjMap(objMap) {
return Object.keys(objMap).reduce((map, name) => {
map[objMap[name]] = name;
return map;
}, Object.create(null));
}
const DECODED_ATTR_MAP = /* @__PURE__ */ decodeObjMap(ATTR_MAP);
function decodeAttr(name) {
return DECODED_ATTR_MAP[name] || name;
}
......@@ -2039,7 +2079,7 @@
} else {
const [name, options] = parseName(rawName);
if (nextValue) {
const invoker = invokers[rawName] = createInvoker(nextValue, instance);
const invoker = invokers[rawName] = createInvoker$1(nextValue, instance);
addEventListener(el, name, invoker, options);
} else if (existingInvoker) {
removeEventListener(el, name, existingInvoker, options);
......@@ -2060,7 +2100,7 @@
}
return [hyphenate(name.slice(2)), options];
}
function createInvoker(initialValue, instance) {
function createInvoker$1(initialValue, instance) {
const invoker = (e) => {
const timeStamp = e.timeStamp || _getNow();
if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
......@@ -2138,6 +2178,30 @@
}
return key in el;
}
const systemModifiers = ["ctrl", "shift", "alt", "meta"];
const modifierGuards = {
stop: (e) => e.stopPropagation(),
prevent: (e) => e.preventDefault(),
self: (e) => e.target !== e.currentTarget,
ctrl: (e) => !e.ctrlKey,
shift: (e) => !e.shiftKey,
alt: (e) => !e.altKey,
meta: (e) => !e.metaKey,
left: (e) => "button" in e && e.button !== 0,
middle: (e) => "button" in e && e.button !== 1,
right: (e) => "button" in e && e.button !== 2,
exact: (e, modifiers) => systemModifiers.some((m) => e[`${m}Key`] && !modifiers.includes(m))
};
const withModifiers = (fn, modifiers) => {
return (event, ...args) => {
for (let i = 0; i < modifiers.length; i++) {
const guard = modifierGuards[modifiers[i]];
if (guard && guard(event, modifiers))
return;
}
return fn(event, ...args);
};
};
extend({ patchProp, forcePatchProp }, nodeOps);
var attrs = ["top", "left", "right", "bottom"];
var inited;
......@@ -2575,7 +2639,7 @@
if (name === ".c") {
this.$.className = value;
} else if (name.indexOf(".e") === 0) {
this.addEvent(name);
this.addEvent(name, value);
} else {
this.$.setAttribute(decodeAttr(name), value);
}
......@@ -2589,20 +2653,16 @@
this.$.removeAttribute(decodeAttr(name));
}
}
addEvent(name) {
const [type] = parseEventName(decodeAttr(name));
addEvent(name, flag) {
const [type, options] = parseEventName(decodeAttr(name));
if (this._listeners[type]) {
{
console.error(formatLog(`tag`, this.tag, this.id, "event[" + type + "] already registered"));
}
return;
}
this._listeners[type] = (evt) => {
UniViewJSBridge.publishHandler(VD_SYNC, [
[ACTION_TYPE_EVENT, this.id, $nne(evt)]
]);
};
this.$.addEventListener(type, this._listeners[type]);
this._listeners[type] = createInvoker(this.id, flag, options);
this.$.addEventListener(type, this._listeners[type], options);
}
removeEvent(name) {
const [type] = parseEventName(decodeAttr(name));
......@@ -2614,6 +2674,30 @@
}
}
}
function createInvoker(id, flag, options) {
const invoker = (evt) => {
const event = $nne(evt);
event.type = normalizeEventType(evt.type, options);
UniViewJSBridge.publishHandler(VD_SYNC, [[ACTION_TYPE_EVENT, id, event]]);
};
if (!flag) {
return invoker;
}
return withModifiers(invoker, resolveModifier(flag));
}
function resolveModifier(flag) {
const modifiers = [];
if (flag & EventModifierFlags.prevent) {
modifiers.push("prevent");
}
if (flag & EventModifierFlags.self) {
modifiers.push("self");
}
if (flag & EventModifierFlags.stop) {
modifiers.push("stop");
}
return modifiers;
}
class UniText extends UniNode {
constructor(id) {
super(id, "#text");
......
......@@ -2,22 +2,54 @@ import {
API_NAVIGATE_BACK,
API_TYPE_NAVIGATE_BACK,
defineAsyncApi,
NavigateBackOptions,
NavigateBackProtocol,
} from '@dcloudio/uni-api'
import { getCurrentPage, initI18nAppMsgsOnce } from '@dcloudio/uni-core'
import {
getCurrentPage,
initI18nAppMsgsOnce,
invokeHook,
} from '@dcloudio/uni-core'
import { useI18n } from '@dcloudio/uni-core'
import { ComponentPublicInstance } from 'vue'
import { ANI_CLOSE, ANI_DURATION } from '../../constants'
import { removePage } from '../../framework/page/getCurrentPages'
import { setStatusBarStyle } from '../../statusBar'
import { backWebview, closeWebview } from './webview'
export const navigateBack = defineAsyncApi<API_TYPE_NAVIGATE_BACK>(
API_NAVIGATE_BACK,
(args, { resolve, reject }) => {
const page = getCurrentPage()
if (!page) {
return
return reject(`getCurrentPages is empty`)
}
if (
invokeHook(page as ComponentPublicInstance, 'onBackPress', {
from: (args as any).from,
})
) {
return resolve()
}
uni.hideToast()
uni.hideLoading()
if (page.$page.meta.isQuit) {
quit()
} else if (page.$page.id === 1 && __uniConfig.realEntryPagePath) {
// condition
__uniConfig.entryPagePath = __uniConfig.realEntryPagePath
delete __uniConfig.realEntryPagePath
uni.reLaunch({
url: '/' + __uniConfig.entryPagePath,
})
} else {
const { delta, animationType, animationDuration } = args
back(delta!, animationType, animationDuration)
}
return resolve()
}
},
NavigateBackProtocol,
NavigateBackOptions
)
let firstBackTime = 0
......@@ -33,3 +65,52 @@ function quit() {
plus.runtime.quit()
}
}
function back(
delta: number,
animationType?: string,
animationDuration?: number
) {
const pages = getCurrentPages()
const len = pages.length
const currentPage = pages[len - 1]
if (delta > 1) {
// 中间页隐藏
pages
.slice(len - delta, len - 1)
.reverse()
.forEach((deltaPage) => {
closeWebview(
plus.webview.getWebviewById(deltaPage.$page.id + ''),
'none',
0
)
})
}
const backPage = function (webview: PlusWebviewWebviewObject) {
if (animationType) {
closeWebview(webview, animationType, animationDuration || ANI_DURATION)
} else {
if (currentPage.$page.openType === 'redirectTo') {
// 如果是 redirectTo 跳转的,需要制定 back 动画
closeWebview(webview, ANI_CLOSE, ANI_DURATION)
} else {
closeWebview(webview, 'auto')
}
}
pages
.slice(len - delta, len)
.forEach((page) => removePage(page as ComponentPublicInstance))
setStatusBarStyle()
}
const webview = plus.webview.getWebviewById(currentPage.$page.id + '')
if (!(currentPage as any).__uniapp_webview) {
return backPage(webview)
}
backWebview(webview, () => {
backPage(webview)
})
}
import { formatLog } from '@dcloudio/uni-shared'
import { WEBVIEW_ID_PREFIX } from '../../constants'
import { navigateFinish } from './utils'
export function closeWebview(
webview: PlusWebviewWebviewObject,
animationType: string,
animationDuration: number
animationDuration?: number
) {
webview[(webview as any).__preload__ ? 'hide' : 'close'](
animationType as any,
......@@ -57,3 +58,27 @@ export function showWebview(
})
}, delay)
}
export function backWebview(
webview: PlusWebviewWebviewObject,
callback: () => void
) {
const children = webview.children()
if (!children || !children.length) {
// 有子 webview
return callback()
}
// 如果页面有subNvues,切使用了webview组件,则返回时子webview会取错,因此需要做id匹配
const childWebview =
children.find((webview) => webview.id!.indexOf(WEBVIEW_ID_PREFIX) === 0) ||
children[0]
childWebview.canBack(({ canBack }) => {
if (canBack) {
childWebview.back() // webview 返回
} else {
callback()
}
})
}
......@@ -3,4 +3,8 @@ 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 ANI_CLOSE = downgrade ? 'slide-out-right' : 'pop-out'
export const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'
export const WEBVIEW_ID_PREFIX = 'webviewId'
......@@ -31,6 +31,8 @@ export default class UniPageNode extends UniNode implements IUniPageNode {
private createdAction: PageCreatedAction
public updateActions: PageAction[] = []
public isUnmounted: boolean
private _update: () => void
constructor(
......@@ -43,6 +45,8 @@ export default class UniPageNode extends UniNode implements IUniPageNode {
this.pageId = pageId
this.pageNode = this
this.isUnmounted = false
this.createAction = [ACTION_TYPE_PAGE_CREATE, options]
this.createdAction = [ACTION_TYPE_PAGE_CREATED]
......@@ -95,6 +99,12 @@ export default class UniPageNode extends UniNode implements IUniPageNode {
return this._id++
}
push(action: PageAction) {
if (this.isUnmounted) {
if (__DEV__) {
console.log(formatLog('PageNode', 'push.prevent', action))
}
return
}
this.updateActions.push(action)
if (__DEV__) {
console.log(formatLog('PageNode', 'push', action))
......@@ -109,11 +119,6 @@ export default class UniPageNode extends UniNode implements IUniPageNode {
setup() {
this.send([this.createAction])
}
// mounted() {
// const { updateActions, createdAction } = this
// updateActions.unshift(createdAction)
// this.update()
// }
update() {
const { updateActions } = this
if (__DEV__) {
......
......@@ -5,42 +5,45 @@ import { setupPage } from './setup'
import __vuePlugin from '../plugin'
import { PageNodeOptions } from '../../../PageAction'
export type VueComponent = DefineComponent
export type VuePageComponent = DefineComponent<PageProps>
const pagesMap = new Map<string, ReturnType<typeof createFactory>>()
export function definePage(pagePath: string, component: VueComponent) {
export function definePage(pagePath: string, component: VuePageComponent) {
pagesMap.set(pagePath, once(createFactory(component)))
}
export interface PageProps {
pageId: number
pagePath: string
pageQuery: Record<string, any>
pageInstance: Page.PageInstance['$page']
interface PageProps {
__pageId: number
__pagePath: string
__pageQuery: Record<string, any>
__pageInstance: Page.PageInstance['$page']
}
export function createPage(
pageId: number,
pagePath: string,
pageQuery: Record<string, any>,
pageInstance: Page.PageInstance['$page'],
__pageId: number,
__pagePath: string,
__pageQuery: Record<string, any>,
__pageInstance: Page.PageInstance['$page'],
pageOptions: PageNodeOptions
) {
return createApp(
pagesMap.get(pagePath)!({
pageId,
pagePath,
pageQuery,
pageInstance,
})
)
.use(__vuePlugin)
.mount(createPageNode(pageId, pageOptions, true) as unknown as Element)
const pageNode = createPageNode(__pageId, pageOptions, true)
const app = createApp(pagesMap.get(__pagePath)!(), {
__pageId,
__pagePath,
__pageQuery,
__pageInstance,
}).use(__vuePlugin)
const oldUnmount = app.unmount
app.unmount = () => {
pageNode.isUnmounted = true
return oldUnmount.call(app)
}
return app.mount(pageNode as unknown as Element)
}
function createFactory(component: VueComponent) {
return (props: PageProps) => {
return setupPage(component, props)
function createFactory(component: VuePageComponent) {
return () => {
return setupPage(component)
}
}
import { formatLog } from '@dcloudio/uni-shared'
import { ComponentPublicInstance } from 'vue'
const pages: ComponentPublicInstance[] = []
......@@ -19,3 +20,17 @@ export function getCurrentPages() {
})
return curPages
}
export function removePage(curPage: ComponentPublicInstance) {
const index = pages.findIndex((page) => page === curPage)
if (index === -1) {
return
}
if (!curPage.$page.meta.isNVue) {
curPage.$.appContext.app.unmount()
}
pages.splice(index, 1)
if (__DEV__) {
console.log(formatLog('removePage', curPage.$page))
}
}
......@@ -16,19 +16,11 @@ import { getStatusbarHeight } from '../../../helpers/statusBar'
import tabBar from '../app/tabBar'
import { addCurrentPage } from './getCurrentPages'
export type OpenType =
| 'navigateTo'
| 'redirectTo'
| 'reLaunch'
| 'switchTab'
| 'navigateBack'
| 'preloadPage'
interface RegisterPageOptions {
url: string
path: string
query: Record<string, string>
openType: OpenType
openType: UniApp.OpenType
webview?: PlusWebviewWebviewObject
vm?: ComponentPublicInstance // nvue vm instance
// eventChannel: unknown
......@@ -74,7 +66,12 @@ export function registerPage({
;(webview as any).__uniapp_route = route
const pageInstance = initPageInternalInstance(url, query, routeOptions.meta)
const pageInstance = initPageInternalInstance(
openType,
url,
query,
routeOptions.meta
)
if (!(webview as any).nvue) {
createPage(
......
import { getRouteOptions, initRouteMeta } from '@dcloudio/uni-core'
import { OpenType } from './register'
export function initRouteOptions(path: string, openType: OpenType) {
export function initRouteOptions(path: string, openType: UniApp.OpenType) {
// 需要序列化一遍
const routeOptions = JSON.parse(
JSON.stringify(getRouteOptions(path)!)
......
import { formatLog } from '@dcloudio/uni-shared'
import { ComponentPublicInstance, getCurrentInstance } from 'vue'
import { PageProps, VueComponent } from './define'
import { VuePageComponent } from './define'
import { addCurrentPage } from './getCurrentPages'
export function setupPage(
component: VueComponent,
{ pageId, pagePath, pageQuery, pageInstance }: PageProps
) {
export function setupPage(component: VuePageComponent) {
const oldSetup = component.setup
component.setup = (_props, ctx) => {
component.inheritAttrs = false // 禁止继承 __pageId 等属性,避免告警
component.setup = (_, ctx) => {
const {
attrs: { __pageId, __pagePath, __pageQuery, __pageInstance },
} = ctx
if (__DEV__) {
console.log(formatLog(pagePath, 'setup'))
console.log(formatLog(__pagePath as string, 'setup'))
}
const instance = getCurrentInstance()!
const pageVm = instance.proxy!
pageVm.$page = pageInstance
addCurrentPage(initScope(pageId, pageVm))
pageVm.$page = __pageInstance as Page.PageInstance['$page']
addCurrentPage(initScope(__pageId as number, pageVm))
if (oldSetup) {
return oldSetup(pageQuery as any, ctx)
return oldSetup(__pageQuery as any, ctx)
}
}
return component
}
function initScope(pageId: number, vm: ComponentPublicInstance) {
const $getAppWebview = () => {
return plus.webview.getWebviewById(pageId + '')
}
vm.$getAppWebview = $getAppWebview
vm.$scope = {
$getAppWebview() {
return plus.webview.getWebviewById(String(pageId))
},
$getAppWebview,
}
return vm
}
import { ON_WEBVIEW_READY } from '../../../constants'
import { createNVueWebview } from './nvue'
import { getPreloadWebview, getWebviewId } from './utils'
import { getWebviewId } from './utils'
import { getPreloadWebview } from './preload'
export * from './init'
......
......@@ -11,6 +11,10 @@ export function setPreloadWebview(webview: PlusWebviewWebviewObject) {
preloadWebview = webview
}
export function getPreloadWebview() {
return preloadWebview
}
export function createPreloadWebview() {
if (!preloadWebview || (preloadWebview as any).__uniapp_route) {
// 不存在,或已被使用
......
......@@ -32,6 +32,9 @@ export function initTitleNView(
return button
}
)
} else {
titleNView[name as keyof PlusWebviewWebviewTitleNViewStyles] =
value as any
}
})
......
import { stringifyQuery } from '@dcloudio/uni-shared'
let id = 2
let preloadWebview: PlusWebviewWebviewObject
export function getWebviewId() {
return id
......@@ -11,10 +10,6 @@ export function genWebviewId() {
return id++
}
export function getPreloadWebview() {
return preloadWebview
}
function encode(val: Parameters<typeof encodeURIComponent>[0]) {
return val as string
}
......
import { formatLog } from '@dcloudio/uni-shared'
type SetStatusBarStyle = typeof plus.navigator.setStatusBarStyle
type StatusBarStyle = Parameters<SetStatusBarStyle>[0]
export let lastStatusBarStyle: StatusBarStyle
let oldSetStatusBarStyle = plus.navigator.setStatusBarStyle
export function restoreOldSetStatusBarStyle(
setStatusBarStyle: SetStatusBarStyle
) {
oldSetStatusBarStyle = setStatusBarStyle
}
export function newSetStatusBarStyle(style: StatusBarStyle) {
lastStatusBarStyle = style
oldSetStatusBarStyle(style)
}
plus.navigator.setStatusBarStyle = newSetStatusBarStyle
export function setStatusBarStyle(statusBarStyle?: StatusBarStyle) {
if (!statusBarStyle) {
const pages = getCurrentPages()
if (!pages.length) {
return
}
statusBarStyle = pages[pages.length - 1].$page
.statusBarStyle as StatusBarStyle
if (!statusBarStyle || statusBarStyle === lastStatusBarStyle) {
return
}
}
if (statusBarStyle === lastStatusBarStyle) {
return
}
if (__DEV__) {
console.log(formatLog('setStatusBarStyle', statusBarStyle))
}
lastStatusBarStyle = statusBarStyle
plus.navigator.setStatusBarStyle(statusBarStyle)
}
......@@ -5,7 +5,10 @@ import {
formatLog,
parseEventName,
UniNodeJSON,
normalizeEventType,
EventModifierFlags,
} from '@dcloudio/uni-shared'
import { withModifiers } from 'vue'
import { VD_SYNC } from '../../../../constants'
import { ACTION_TYPE_EVENT } from '../../../../PageAction'
import { UniNode } from './UniNode'
......@@ -32,7 +35,7 @@ export class UniElement extends UniNode {
if (name === '.c') {
this.$.className = value as string
} else if (name.indexOf('.e') === 0) {
this.addEvent(name)
this.addEvent(name, value as number)
} else {
this.$.setAttribute(decodeAttr(name), value as string)
}
......@@ -46,8 +49,8 @@ export class UniElement extends UniNode {
this.$.removeAttribute(decodeAttr(name))
}
}
addEvent(name: string) {
const [type] = parseEventName(decodeAttr(name))
addEvent(name: string, flag: number) {
const [type, options] = parseEventName(decodeAttr(name))
if (this._listeners[type]) {
if (__DEV__) {
console.error(
......@@ -61,12 +64,8 @@ export class UniElement extends UniNode {
}
return
}
this._listeners[type] = (evt: Event) => {
UniViewJSBridge.publishHandler(VD_SYNC, [
[ACTION_TYPE_EVENT, this.id, normalizeNativeEvent(evt)],
])
}
this.$.addEventListener(type, this._listeners[type])
this._listeners[type] = createInvoker(this.id, flag, options)
this.$.addEventListener(type, this._listeners[type], options)
}
removeEvent(name: string) {
const [type] = parseEventName(decodeAttr(name))
......@@ -80,3 +79,33 @@ export class UniElement extends UniNode {
}
}
}
function createInvoker(
id: number,
flag: number,
options?: AddEventListenerOptions
) {
const invoker = (evt: Event) => {
const event = normalizeNativeEvent(evt)
;(event as any).type = normalizeEventType(evt.type, options)
UniViewJSBridge.publishHandler(VD_SYNC, [[ACTION_TYPE_EVENT, id, event]])
}
if (!flag) {
return invoker
}
return withModifiers(invoker, resolveModifier(flag))
}
function resolveModifier(flag: number) {
const modifiers: string[] = []
if (flag & EventModifierFlags.prevent) {
modifiers.push('prevent')
}
if (flag & EventModifierFlags.self) {
modifiers.push('self')
}
if (flag & EventModifierFlags.stop) {
modifiers.push('stop')
}
return modifiers
}
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uniManifestJsonPlugin = void 0;
const path_1 = __importDefault(require("path"));
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
function uniManifestJsonPlugin() {
let manifestJson;
......@@ -12,6 +16,7 @@ function uniManifestJsonPlugin() {
if (!opts.filter(id)) {
return;
}
this.addWatchFile(path_1.default.resolve(process.env.UNI_INPUT_DIR, 'manifest.json'));
manifestJson = uni_cli_shared_1.normalizeAppManifestJson(JSON.parse(code), uni_cli_shared_1.parsePagesJsonOnce(process.env.UNI_INPUT_DIR, process.env.UNI_PLATFORM));
return '';
},
......
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.uniPagesJsonPlugin = void 0;
const path_1 = __importDefault(require("path"));
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
function uniPagesJsonPlugin() {
let pagesJson;
......@@ -12,7 +16,12 @@ function uniPagesJsonPlugin() {
if (!opts.filter(id)) {
return;
}
this.addWatchFile(path_1.default.resolve(process.env.UNI_INPUT_DIR, 'pages.json'));
pagesJson = uni_cli_shared_1.normalizePagesJson(code, process.env.UNI_PLATFORM);
// TODO subpackages
pagesJson.pages.forEach((page) => {
this.addWatchFile(path_1.default.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue'));
});
return (`import './manifest.json.js'\n` + uni_cli_shared_1.normalizeAppPagesJson(pagesJson));
},
generateBundle() {
......
import path from 'path'
import { Plugin } from 'vite'
import {
......@@ -16,6 +17,9 @@ export function uniManifestJsonPlugin(): Plugin {
if (!opts.filter(id)) {
return
}
this.addWatchFile(
path.resolve(process.env.UNI_INPUT_DIR, 'manifest.json')
)
manifestJson = normalizeAppManifestJson(
JSON.parse(code),
parsePagesJsonOnce(
......
import path from 'path'
import { Plugin } from 'vite'
import {
......@@ -18,7 +19,14 @@ export function uniPagesJsonPlugin(): Plugin {
if (!opts.filter(id)) {
return
}
this.addWatchFile(path.resolve(process.env.UNI_INPUT_DIR, 'pages.json'))
pagesJson = normalizePagesJson(code, process.env.UNI_PLATFORM)
// TODO subpackages
pagesJson.pages.forEach((page) => {
this.addWatchFile(
path.resolve(process.env.UNI_INPUT_DIR, page.path + '.vue')
)
})
return (
`import './manifest.json.js'\n` + normalizeAppPagesJson(pagesJson)
)
......
......@@ -10654,6 +10654,22 @@ function createInvoker(initialValue, instance) {
)
}
invoker.value = initialValue
const modifiers = new Set()
// 合并 modifiers
if (isArray(invoker.value)) {
invoker.value.forEach((v) => {
if (v.modifiers) {
v.modifiers.forEach((m) => {
modifiers.add(m)
})
}
})
} else if (invoker.value.modifiers) {
invoker.value.modifiers.forEach((m) => {
modifiers.add(m)
})
}
invoker.modifiers = [...modifiers]
return invoker
}
......@@ -11228,13 +11244,16 @@ const modifierGuards = {
* @private
*/
const withModifiers = (fn, modifiers) => {
return (event, ...args) => {
// fixed by xxxxxx 补充 modifiers 标记,方便同步给 view 层
const wrapper = (event, ...args) => {
for (let i = 0; i < modifiers.length; i++) {
const guard = modifierGuards[modifiers[i]]
if (guard && guard(event, modifiers)) return
}
return fn(event, ...args)
}
wrapper.modifiers = modifiers
return wrapper
}
// Kept for 2.x compat.
// Note: IE11 compat for `spacebar` and `del` is removed for now.
......
......@@ -5,6 +5,43 @@ Object.defineProperty(exports, '__esModule', { value: true });
var vue = require('vue');
var shared = require('@vue/shared');
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ shared.extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
const sanitise = (val) => (val && JSON.parse(JSON.stringify(val))) || val;
const UNI_SSR = '__uniSSR';
const UNI_SSR_DATA = 'data';
......
import { shallowRef, ref, getCurrentInstance, isInSSRComponentSetup, injectHook } from 'vue';
import { hasOwn, isString } from '@vue/shared';
import { extend, hasOwn, isString } from '@vue/shared';
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
const sanitise = (val) => (val && JSON.parse(JSON.stringify(val))) || val;
const UNI_SSR = '__uniSSR';
const UNI_SSR_DATA = 'data';
......@@ -16,6 +53,9 @@ function assertKey(key, shallow = false) {
}
const ssrClientRef = (value, key, shallow = false) => {
const valRef = shallow ? shallowRef(value) : ref(value);
if (__PLATFORM__ !== 'h5') {
return valRef;
}
const __uniSSR = window[UNI_SSR];
if (!__uniSSR) {
return valRef;
......
......@@ -33,12 +33,13 @@ interface CheckUpdateCache {
}
interface CheckVersionRequest {
vv: 3
device: string
appid?: string
vid?: string
vtype: CheckUpdateOptions['versionType']
vcode: string
[name: string]: CheckUpdatePlatform | undefined | string
[name: string]: CheckUpdatePlatform | undefined | string | number
}
interface CheckVersionResponse {
......@@ -210,6 +211,7 @@ export function createPostData(
updateCache: CheckUpdateCache
) {
const data: CheckVersionRequest = {
vv: 3,
device: md5(getMac()),
vtype: versionType,
vcode: compilerVersion,
......
import { Plugin } from 'vite'
import { ParserOptions } from '@vue/compiler-core'
import { CompilerOptions } from '@vue/compiler-sfc'
export interface UniVitePlugin extends Plugin {
uni?: {
compilerOptions?: {
isNativeTag: ParserOptions['isNativeTag']
isCustomElement: ParserOptions['isCustomElement']
directiveTransforms?: CompilerOptions['directiveTransforms']
}
transformEvent?: Record<string, string>
}
......
......@@ -91,6 +91,7 @@ export function normalizePullToRefreshRpx(
}
export function initPageInternalInstance(
openType: UniApp.OpenType,
url: string,
pageQuery: Record<string, any>,
meta: UniApp.PageRouteMeta
......@@ -103,5 +104,6 @@ export function initPageInternalInstance(
fullPath: url,
options: pageQuery,
meta,
openType,
}
}
......@@ -487,7 +487,7 @@ function normalizePullToRefreshRpx(pullToRefresh) {
}
return pullToRefresh;
}
function initPageInternalInstance(url, pageQuery, meta) {
function initPageInternalInstance(openType, url, pageQuery, meta) {
const { id, route } = meta;
return {
id,
......@@ -495,7 +495,8 @@ function initPageInternalInstance(url, pageQuery, meta) {
route,
fullPath: url,
options: pageQuery,
meta
meta,
openType
};
}
function invokeHook(vm, name, args) {
......@@ -1220,7 +1221,7 @@ function getApiCallbacks(args) {
}
return apiCallbacks;
}
function normalizeErrMsg(errMsg, name) {
function normalizeErrMsg$1(errMsg, name) {
if (!errMsg || errMsg.indexOf(":fail") === -1) {
return name + ":ok";
}
......@@ -1237,7 +1238,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
res.errMsg = normalizeErrMsg$1(res.errMsg, name);
shared.isFunction(beforeAll) && beforeAll(res);
if (res.errMsg === name + ":ok") {
shared.isFunction(beforeSuccess) && beforeSuccess(res);
......@@ -1317,6 +1318,13 @@ function beforeInvokeApi(name, args, protocol, options) {
return errMsg;
}
}
function normalizeErrMsg(errMsg) {
if (errMsg instanceof Error) {
console.error(errMsg);
return errMsg.message;
}
return errMsg;
}
function wrapperTaskApi(name, fn, protocol, options) {
return (args) => {
const id = createAsyncApiCallback(name, args, options);
......@@ -1326,7 +1334,7 @@ function wrapperTaskApi(name, fn, protocol, options) {
}
return fn(args, {
resolve: (res) => invokeSuccess(id, name, res),
reject: (errMsg2, errRes) => invokeFail(id, name, errMsg2, errRes)
reject: (errMsg2, errRes) => invokeFail(id, name, normalizeErrMsg(errMsg2), errRes)
});
};
}
......@@ -3139,6 +3147,10 @@ const props$n = /* @__PURE__ */ shared.extend({}, props$o, {
placeholderClass: {
type: String,
default: "input-placeholder"
},
textContentType: {
type: String,
default: ""
}
});
var Input = /* @__PURE__ */ defineBuiltInComponent({
......@@ -3148,7 +3160,8 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
setup(props2, {
emit: emit2
}) {
const INPUT_TYPES = ["text", "number", "idcard", "digit", "password"];
const INPUT_TYPES = ["text", "number", "idcard", "digit", "password", "tel"];
const AUTOCOMPLETES = ["off", "one-time-code"];
const type = vue.computed(() => {
let type2 = "";
switch (props2.type) {
......@@ -3169,6 +3182,12 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
}
return props2.password ? "password" : type2;
});
const autocomplete = vue.computed(() => {
const camelizeIndex = AUTOCOMPLETES.indexOf(props2.textContentType);
const kebabCaseIndex = AUTOCOMPLETES.indexOf(shared.hyphenate(props2.textContentType));
const index2 = camelizeIndex !== -1 ? camelizeIndex : kebabCaseIndex !== -1 ? kebabCaseIndex : 0;
return AUTOCOMPLETES[index2];
});
let cache = vue.ref("");
let resetCache;
const rootRef = vue.ref(null);
......@@ -3240,9 +3259,9 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
"enterkeyhint": props2.confirmType,
"pattern": props2.type === "number" ? "[0-9]*" : void 0,
"class": "uni-input-input",
"autocomplete": "off",
"autocomplete": autocomplete.value,
"onKeyup": onKeyUpEnter
}, null, 40, ["value", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "onKeyup"]);
}, null, 40, ["value", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "autocomplete", "onKeyup"]);
return vue.createVNode("uni-input", {
"ref": rootRef
}, {
......@@ -5176,7 +5195,7 @@ var index$i = /* @__PURE__ */ defineBuiltInComponent({
MODE: 3
},
props: props$e,
emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort"],
emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort", "update:refresherTriggered"],
setup(props2, {
emit: emit2,
slots
......@@ -5192,7 +5211,7 @@ var index$i = /* @__PURE__ */ defineBuiltInComponent({
scrollTopNumber,
scrollLeftNumber
} = useScrollViewState(props2);
useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content);
useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2);
const mainStyle = vue.computed(() => {
let style = "";
props2.scrollX ? style += "overflow-x:auto;" : style += "overflow-x:hidden;";
......@@ -5289,7 +5308,7 @@ function useScrollViewState(props2) {
scrollLeftNumber
};
}
function useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content) {
function useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2) {
let beforeRefreshing = false;
let triggerAbort = false;
let __transitionEnd = () => {
......@@ -5409,6 +5428,7 @@ function useScrollViewLoader(props2, state, scrollTopNumber, scrollLeftNumber, t
if (!beforeRefreshing) {
beforeRefreshing = true;
trigger("refresherrefresh", {}, {});
emit2("update:refresherTriggered", true);
}
break;
case "restore":
......@@ -6658,9 +6678,9 @@ function getCurrentPages$1() {
function initPublicPage(route) {
const meta = usePageMeta();
if (!__UNI_FEATURE_PAGES__) {
return initPageInternalInstance(__uniRoutes[0].path, {}, meta);
return initPageInternalInstance("navigateTo", __uniRoutes[0].path, {}, meta);
}
return initPageInternalInstance(route.fullPath, {}, meta);
return initPageInternalInstance("navigateTo", route.fullPath, {}, meta);
}
function initPage(vm) {
const route = vm.$route;
......
......@@ -737,7 +737,7 @@ var safeAreaInsets = {
onChange,
offChange
};
var D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out = safeAreaInsets;
var out = safeAreaInsets;
const onEventPrevent = /* @__PURE__ */ withModifiers(() => {
}, ["prevent"]);
const onEventStop = /* @__PURE__ */ withModifiers(() => {
......@@ -749,10 +749,10 @@ function getWindowOffset() {
const left = parseInt(style.getPropertyValue("--window-left"));
const right = parseInt(style.getPropertyValue("--window-right"));
return {
top: top ? top + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top : 0,
bottom: bottom ? bottom + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom : 0,
left: left ? left + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left : 0,
right: right ? right + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right : 0
top: top ? top + out.top : 0,
bottom: bottom ? bottom + out.bottom : 0,
left: left ? left + out.left : 0,
right: right ? right + out.right : 0
};
}
function updateCssVar(cssVars) {
......@@ -915,7 +915,7 @@ function normalizePullToRefreshRpx(pullToRefresh) {
}
return pullToRefresh;
}
function initPageInternalInstance(url, pageQuery, meta) {
function initPageInternalInstance(openType, url, pageQuery, meta) {
const { id: id2, route } = meta;
return {
id: id2,
......@@ -923,7 +923,8 @@ function initPageInternalInstance(url, pageQuery, meta) {
route,
fullPath: url,
options: pageQuery,
meta
meta,
openType
};
}
function invokeHook(vm, name, args) {
......@@ -2341,7 +2342,7 @@ function getApiCallbacks(args) {
}
return apiCallbacks;
}
function normalizeErrMsg(errMsg, name) {
function normalizeErrMsg$1(errMsg, name) {
if (!errMsg || errMsg.indexOf(":fail") === -1) {
return name + ":ok";
}
......@@ -2358,7 +2359,7 @@ function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } =
const callbackId = invokeCallbackId++;
addInvokeCallback(callbackId, name, (res) => {
res = res || {};
res.errMsg = normalizeErrMsg(res.errMsg, name);
res.errMsg = normalizeErrMsg$1(res.errMsg, name);
isFunction(beforeAll) && beforeAll(res);
if (res.errMsg === name + ":ok") {
isFunction(beforeSuccess) && beforeSuccess(res);
......@@ -2474,6 +2475,13 @@ function wrapperOffApi(name, fn, options) {
}
};
}
function normalizeErrMsg(errMsg) {
if (errMsg instanceof Error) {
console.error(errMsg);
return errMsg.message;
}
return errMsg;
}
function wrapperTaskApi(name, fn, protocol, options) {
return (args) => {
const id2 = createAsyncApiCallback(name, args, options);
......@@ -2483,7 +2491,7 @@ function wrapperTaskApi(name, fn, protocol, options) {
}
return fn(args, {
resolve: (res) => invokeSuccess(id2, name, res),
reject: (errMsg2, errRes) => invokeFail(id2, name, errMsg2, errRes)
reject: (errMsg2, errRes) => invokeFail(id2, name, normalizeErrMsg(errMsg2), errRes)
});
};
}
......@@ -8159,6 +8167,10 @@ const props$u = /* @__PURE__ */ extend({}, props$v, {
placeholderClass: {
type: String,
default: "input-placeholder"
},
textContentType: {
type: String,
default: ""
}
});
var Input = /* @__PURE__ */ defineBuiltInComponent({
......@@ -8168,7 +8180,8 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
setup(props2, {
emit: emit2
}) {
const INPUT_TYPES = ["text", "number", "idcard", "digit", "password"];
const INPUT_TYPES = ["text", "number", "idcard", "digit", "password", "tel"];
const AUTOCOMPLETES = ["off", "one-time-code"];
const type = computed(() => {
let type2 = "";
switch (props2.type) {
......@@ -8189,6 +8202,12 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
}
return props2.password ? "password" : type2;
});
const autocomplete = computed(() => {
const camelizeIndex = AUTOCOMPLETES.indexOf(props2.textContentType);
const kebabCaseIndex = AUTOCOMPLETES.indexOf(hyphenate(props2.textContentType));
const index2 = camelizeIndex !== -1 ? camelizeIndex : kebabCaseIndex !== -1 ? kebabCaseIndex : 0;
return AUTOCOMPLETES[index2];
});
let cache = ref("");
let resetCache;
const rootRef = ref(null);
......@@ -8260,9 +8279,9 @@ var Input = /* @__PURE__ */ defineBuiltInComponent({
"enterkeyhint": props2.confirmType,
"pattern": props2.type === "number" ? "[0-9]*" : void 0,
"class": "uni-input-input",
"autocomplete": "off",
"autocomplete": autocomplete.value,
"onKeyup": onKeyUpEnter
}, null, 40, ["value", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "onKeyup"]);
}, null, 40, ["value", "disabled", "type", "maxlength", "step", "enterkeyhint", "pattern", "autocomplete", "onKeyup"]);
return createVNode("uni-input", {
"ref": rootRef
}, {
......@@ -11302,7 +11321,7 @@ var ScrollView = /* @__PURE__ */ defineBuiltInComponent({
MODE: 3
},
props: props$l,
emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort"],
emits: ["scroll", "scrolltoupper", "scrolltolower", "refresherrefresh", "refresherrestore", "refresherpulling", "refresherabort", "update:refresherTriggered"],
setup(props2, {
emit: emit2,
slots
......@@ -11318,7 +11337,7 @@ var ScrollView = /* @__PURE__ */ defineBuiltInComponent({
scrollTopNumber,
scrollLeftNumber
} = useScrollViewState(props2);
useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content);
useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2);
const mainStyle = computed(() => {
let style = "";
props2.scrollX ? style += "overflow-x:auto;" : style += "overflow-x:hidden;";
......@@ -11415,7 +11434,7 @@ function useScrollViewState(props2) {
scrollLeftNumber
};
}
function useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content) {
function useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber, trigger, rootRef, main, content, emit2) {
let _lastScrollTime = 0;
let beforeRefreshing = false;
let toUpperNumber = 0;
......@@ -11581,6 +11600,7 @@ function useScrollViewLoader(props2, state2, scrollTopNumber, scrollLeftNumber,
if (!beforeRefreshing) {
beforeRefreshing = true;
trigger("refresherrefresh", {}, {});
emit2("update:refresherTriggered", true);
}
break;
case "restore":
......@@ -13087,7 +13107,7 @@ function normalizePageMeta(pageMeta) {
}, pageMeta.pullToRefresh));
const { type, style } = navigationBar;
if (style !== "custom" && type !== "transparent") {
pullToRefresh.offset += NAVBAR_HEIGHT + D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top;
pullToRefresh.offset += NAVBAR_HEIGHT + out.top;
}
pageMeta.pullToRefresh = pullToRefresh;
}
......@@ -13223,9 +13243,9 @@ function createPageState(type, __id__) {
function initPublicPage(route) {
const meta = usePageMeta();
if (!__UNI_FEATURE_PAGES__) {
return initPageInternalInstance(__uniRoutes[0].path, {}, meta);
return initPageInternalInstance("navigateTo", __uniRoutes[0].path, {}, meta);
}
return initPageInternalInstance(route.fullPath, {}, meta);
return initPageInternalInstance("navigateTo", route.fullPath, {}, meta);
}
function initPage(vm) {
const route = vm.$route;
......@@ -15262,7 +15282,7 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
const windowWidth = getWindowWidth(screenWidth);
let windowHeight = window.innerHeight;
const language = navigator.language;
const statusBarHeight = D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top;
const statusBarHeight = out.top;
let osname;
let osversion;
let model;
......@@ -15375,12 +15395,12 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
const system = `${osname} ${osversion}`;
const platform = osname.toLocaleLowerCase();
const safeArea = {
left: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left,
right: windowWidth - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
top: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top,
bottom: windowHeight - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom,
width: windowWidth - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
height: windowHeight - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top - D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom
left: out.left,
right: windowWidth - out.right,
top: out.top,
bottom: windowHeight - out.bottom,
width: windowWidth - out.left - out.right,
height: windowHeight - out.top - out.bottom
};
const { top: windowTop, bottom: windowBottom } = getWindowOffset();
windowHeight -= windowTop;
......@@ -15400,10 +15420,10 @@ const getSystemInfoSync = /* @__PURE__ */ defineSyncApi("getSystemInfoSync", ()
model,
safeArea,
safeAreaInsets: {
top: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.top,
right: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.right,
bottom: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.bottom,
left: D__DCloud_local_git_uniAppNext_node_modules_safeAreaInsets_out.left
top: out.top,
right: out.right,
bottom: out.bottom,
left: out.left
}
};
});
......
......@@ -78,10 +78,11 @@ export function createPageState(type: NavigateType, __id__?: number) {
function initPublicPage(route: RouteLocationNormalizedLoaded) {
const meta = usePageMeta()
if (!__UNI_FEATURE_PAGES__) {
return initPageInternalInstance(__uniRoutes[0].path, {}, meta)
return initPageInternalInstance('navigateTo', __uniRoutes[0].path, {}, meta)
}
return initPageInternalInstance(route.fullPath, {}, meta)
return initPageInternalInstance('navigateTo', route.fullPath, {}, meta)
}
export function initPage(vm: ComponentPublicInstance) {
......
......@@ -234,7 +234,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initVueIds(vueIds, mpInstance) {
if (!vueIds) {
......
......@@ -225,7 +225,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initBehavior(options) {
return Behavior(options);
......
......@@ -225,7 +225,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initBehavior(options) {
return Behavior(options);
......
......@@ -228,7 +228,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initBehavior(options) {
return Behavior(options);
......
import { isFunction, isSymbol, extend, isMap, isObject, toRawType, def, isArray, isString, isPromise, toHandlerKey, remove, EMPTY_OBJ, camelize, capitalize, normalizeClass, normalizeStyle, isOn, NOOP, isGloballyWhitelisted, isIntegerKey, hasOwn, hasChanged, NO, invokeArrayFns as invokeArrayFns$1, makeMap, isSet, toNumber, hyphenate, isReservedProp, EMPTY_ARR, toTypeString } from '@vue/shared';
import { isFunction, extend, isSymbol, isMap, isObject, toRawType, def, isArray, isString, isPromise, toHandlerKey, remove, EMPTY_OBJ, camelize, capitalize, normalizeClass, normalizeStyle, isOn, NOOP, isGloballyWhitelisted, isIntegerKey, hasOwn, hasChanged, NO, invokeArrayFns as invokeArrayFns$1, makeMap, isSet, toNumber, hyphenate, isReservedProp, EMPTY_ARR, toTypeString } from '@vue/shared';
export { camelize } from '@vue/shared';
import { injectHook as injectHook$1 } from 'vue';
......@@ -13,6 +13,43 @@ function applyOptions$1(options, instance, publicThis) {
});
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
......
......@@ -225,7 +225,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initBehavior(options) {
return Behavior(options);
......
......@@ -225,7 +225,44 @@ function stringifyQuery(obj, encodeStr = encode) {
.join('&')
: null;
return res ? `?${res}` : '';
}
}
const EVENT_MAP = {
onClick: '.e0',
onChange: '.e1',
onInput: '.e2',
onLoad: '.e3',
onError: '.e4',
onTouchstart: '.e5',
onTouchmove: '.e6',
onTouchcancel: '.e7',
onTouchend: '.e8',
onLongpress: '.e9',
onTransitionend: '.ea',
onAnimationstart: '.eb',
onAnimationiteration: '.ec',
onAnimationend: '.ed',
onTouchforcechange: '.ee',
};
const OPTIONS = [
'Capture',
'CaptureOnce',
'CapturePassive',
'CaptureOncePassive',
'Once',
'OncePassive',
'Passive',
];
/*#__PURE__*/ extend({
class: '.c',
style: '.s',
}, Object.keys(EVENT_MAP).reduce((res, name) => {
const value = EVENT_MAP[name];
res[name] = value;
OPTIONS.forEach((v, i) => {
res[name + v] = value + i;
});
return res;
}, Object.create(null)));
function initBehavior(options) {
return Behavior(options);
......
......@@ -53,10 +53,16 @@ export declare const defaultRpx2Unit: {
unitPrecision: number;
};
export declare function encodeAttr(name: string): string;
export declare function encodeAttr(name: string): any;
export declare function encodeTag(tag: string): string | number;
export declare const EventModifierFlags: {
stop: number;
prevent: number;
self: number;
};
export declare function formatDateTime({ date, mode }: {
date?: Date | undefined;
mode?: string | undefined;
......@@ -91,6 +97,7 @@ export declare function isServiceNativeTag(tag: string): boolean;
export declare interface IUniPageNode {
pageId: number;
pageNode: IUniPageNode | null;
isUnmounted: boolean;
genId: () => number;
push: (...args: any[]) => void;
onCreate: (thisNode: UniNode, nodeName: string | number) => UniNode;
......@@ -114,6 +121,8 @@ export declare const NODE_TYPE_TEXT = 3;
export declare function normalizeDataset(el: Element): any;
export declare function normalizeEventType(type: string, options?: AddEventListenerOptions): string;
export declare function normalizeTarget(el: HTMLElement): {
id: string;
dataset: DOMStringMap & Record<string, any>;
......@@ -256,6 +265,7 @@ export declare class UniEvent {
export declare interface UniEventListener {
(evt: UniEvent): void;
modifiers?: string[];
}
declare interface UniEventOptions {
......@@ -267,7 +277,7 @@ declare class UniEventTarget {
private _listeners;
dispatchEvent(evt: UniEvent): boolean;
addEventListener(type: string, listener: UniEventListener, options?: AddEventListenerOptions): void;
removeEventListener(type: string, callback: UniEventListener, options?: EventListenerOptions): void;
removeEventListener(type: string, callback: UniEventListener, options?: AddEventListenerOptions): void;
}
export declare class UniInputElement extends UniElement {
......
import { extend, capitalize, camelize, hyphenate } from '@vue/shared'
import { formatLog } from '../log'
import { UniElement } from './Element'
import { UniNode } from './Node'
export function normalizeEventType(type: string) {
export function normalizeEventType(
type: string,
options?: AddEventListenerOptions
) {
if (options) {
if (options.capture) {
type += 'Capture'
}
if (options.once) {
type += 'Once'
}
if (options.passive) {
type += 'Passive'
}
}
return `on${capitalize(camelize(type))}`
}
export interface UniEventListener {
(evt: UniEvent): void
modifiers?: string[]
}
interface UniEventOptions {
......@@ -28,7 +42,7 @@ export class UniEvent {
_end: boolean = false
constructor(type: string, opts: UniEventOptions) {
this.type = type.toLowerCase()
this.type = type
this.bubbles = !!opts.bubbles
this.cancelable = !!opts.cancelable
}
......@@ -46,6 +60,19 @@ export class UniEvent {
}
}
function createUniEvent(evt: Record<string, any>) {
if (evt instanceof UniEvent) {
return evt
}
const [type] = parseEventName(evt.type)
const uniEvent = new UniEvent(type, {
bubbles: false,
cancelable: false,
})
extend(uniEvent, evt)
return uniEvent
}
export class UniEventTarget {
private _listeners: Record<string, UniEventListener[]> = {}
......@@ -61,14 +88,17 @@ export class UniEventTarget {
}
return false
}
// 格式化事件类型
const event = createUniEvent(evt)
const len = listeners.length
for (let i = 0; i < len; i++) {
listeners[i].call(this, evt)
if (evt._end) {
listeners[i].call(this, event)
if (event._end) {
break
}
}
return evt.cancelable && evt.defaultPrevented
return event.cancelable && event.defaultPrevented
}
addEventListener(
......@@ -76,27 +106,17 @@ export class UniEventTarget {
listener: UniEventListener,
options?: AddEventListenerOptions
): void {
const isOnce = options && options.once
if (isOnce) {
const wrapper = function (this: UniElement, evt: UniEvent) {
listener.apply(this, [evt])
this.removeEventListener(type, wrapper, options)
}
return this.addEventListener(
type,
wrapper,
extend(options, { once: false })
)
}
type = normalizeEventType(type, options)
;(this._listeners[type] || (this._listeners[type] = [])).push(listener)
}
removeEventListener(
type: string,
callback: UniEventListener,
options?: EventListenerOptions
options?: AddEventListenerOptions
): void {
const listeners = this._listeners[type.toLowerCase()]
type = normalizeEventType(type, options)
const listeners = this._listeners[type]
if (!listeners) {
return
}
......
......@@ -13,7 +13,7 @@ export class UniTextNode extends UniBaseNode {
set nodeValue(text: string) {
this._text = text
if (this.pageNode) {
if (this.pageNode && !this.pageNode.isUnmounted) {
this.pageNode.onNodeValue(this, text)
}
}
......
import { ATTR_MAP, COMPONENT_MAP } from './encode'
const DECODED_ATTR_MAP = /*#__PURE__*/ Object.keys(ATTR_MAP).reduce(
(map, name) => {
map[ATTR_MAP[name as keyof typeof ATTR_MAP]] = name
function decodeObjMap(objMap: Record<string, string>) {
return Object.keys(objMap).reduce((map, name) => {
map[objMap[name]] = name
return map
},
Object.create(null)
)
}, Object.create(null))
}
function decodeArrMap(objMap: Record<string, number>) {
return Object.keys(objMap).reduce(
(arr, name) => {
arr.push(name.toLowerCase())
return arr
},
['']
)
}
const DECODED_ATTR_MAP = /*#__PURE__*/ decodeObjMap(ATTR_MAP)
export function decodeAttr(name: string) {
return DECODED_ATTR_MAP[name as keyof typeof DECODED_ATTR_MAP] || name
}
const DECODED_COMPONENT_ARR = /*#__PURE__*/ Object.keys(COMPONENT_MAP).reduce(
(arr, name) => {
arr.push(name.toLowerCase())
return arr
},
['']
)
const DECODED_COMPONENT_ARR = /*#__PURE__*/ decodeArrMap(COMPONENT_MAP)
export function decodeTag(tag: string | number) {
return (DECODED_COMPONENT_ARR[tag as number] || tag) as string
......
export { UniCommentNode } from './Comment'
export { UniElement, UniInputElement, UniTextAreaElement } from './Element'
export { UniEvent, UniEventListener, parseEventName } from './Event'
export {
UniEvent,
UniEventListener,
parseEventName,
normalizeEventType,
} from './Event'
export {
NODE_TYPE_PAGE,
NODE_TYPE_ELEMENT,
......@@ -14,3 +19,4 @@ export {
export { UniTextNode } from './Text'
export { encodeAttr, encodeTag } from './encode'
export { decodeAttr, decodeTag } from './decode'
export { EventModifierFlags } from './encode'
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册