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

wip(app): uni-app-plus

上级 b3b2d134
module.exports = {
preset: 'ts-jest',
setupFilesAfterEnv: ['./scripts/setupJestEnv.ts'],
globals: {
__DEV__: true,
__TEST__: true,
__VERSION__: require('./package.json').version,
__BROWSER__: false,
__GLOBAL__: false,
__VUE_OPTIONS_API__: true
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
},
coverageDirectory: 'coverage',
coverageReporters: ['html', 'lcov', 'text'],
......@@ -14,9 +16,10 @@ module.exports = {
watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
moduleNameMapper: {
'^@dcloudio/(.*?)$': '<rootDir>/packages/$1/src'
'^@dcloudio/(.*?)$': '<rootDir>/packages/$1/src',
},
rootDir: __dirname,
testMatch: ['<rootDir>/packages/**/__tests__/**/*spec.[jt]s?(x)'],
testPathIgnorePatterns: ['/node_modules/']
testPathIgnorePatterns: ['/node_modules/'],
transform: { 'service\\.runtime\\.esm\\.js$': ['ts-jest'] },
}
import { UniNodeJSON } from '@dcloudio/uni-shared'
import {
ACTION_TYPE_INSERT,
ACTION_TYPE_REMOVE,
ACTION_TYPE_REMOVE_ATTRIBUTE,
ACTION_TYPE_SET_ATTRIBUTE,
ACTION_TYPE_SET_TEXT,
createPageNode,
InsertAction,
SetAttributeAction,
} from '../../../src/service/framework/dom/Page'
import {
createElement,
createTextNode,
} from '../../../../uni-app-vue/lib/service.runtime.esm'
describe('dom', () => {
const pageId = 1
const root = createPageNode(pageId, {
version: 1,
locale: 'zh_CN',
disableScroll: false,
onPageScroll: false,
onPageReachBottom: false,
onReachBottomDistance: 50,
statusbarHeight: 24,
windowTop: 0,
windowBottom: 0,
})
test('proxyNode', () => {
const viewElem = createElement('view')
viewElem.setAttribute('id', 'view')
root.appendChild(viewElem)
viewElem.setAttribute('hidden', true)
const { updateActions } = root
const addElementAction = updateActions[0] as InsertAction
expect(addElementAction[0]).toBe(ACTION_TYPE_INSERT)
expect(addElementAction[1]).toBe(1) // nodeId
expect(addElementAction[2]).toBe(0) // parentNodeId
expect(addElementAction[3]).toBe(0) // index
const elementJson = addElementAction[4] as UniNodeJSON
expect(elementJson.a.id).toBe('view')
const setAttributeAction = updateActions[1] as SetAttributeAction
expect(setAttributeAction[0]).toBe(ACTION_TYPE_SET_ATTRIBUTE)
expect(setAttributeAction[1]).toBe(1)
expect(setAttributeAction[2]).toBe('hidden')
expect(setAttributeAction[3]).toBe(true)
root.updateActions.length = 0
viewElem.removeAttribute('hidden')
const {
updateActions: [removeAttributeAction],
} = root
expect(removeAttributeAction[0]).toBe(ACTION_TYPE_REMOVE_ATTRIBUTE)
expect(removeAttributeAction[1]).toBe(1)
expect(removeAttributeAction[2]).toBe('hidden')
root.updateActions.length = 0
viewElem.textContent = 'text'
const {
updateActions: [setTextAction],
} = root
expect(setTextAction[0]).toBe(ACTION_TYPE_SET_TEXT)
expect(setTextAction[1]).toBe(1)
expect(setTextAction[2]).toBe('text')
root.updateActions.length = 0
root.removeChild(viewElem)
const {
updateActions: [removeChildAction],
} = root
expect(removeChildAction[0]).toBe(ACTION_TYPE_REMOVE)
expect(removeChildAction[1]).toBe(1)
expect(removeChildAction[2]).toBe(0)
root.updateActions.length = 0
const textNode = createTextNode('hello')
root.appendChild(textNode)
const {
updateActions: [addTextNodeAction],
} = root
expect(addTextNodeAction[0]).toBe(ACTION_TYPE_INSERT)
expect(addTextNodeAction[1]).toBe(2)
expect(addTextNodeAction[2]).toBe(0)
expect(addTextNodeAction[3]).toBe(0)
const textNodeJson = addTextNodeAction[4] as UniNodeJSON
expect(textNodeJson.t).toBe('hello')
root.updateActions.length = 0
const clickFn = () => {}
textNode.addEventListener('click', clickFn)
const {
updateActions: [addEventListenerAction],
} = root
expect(addEventListenerAction[0]).toBe(ACTION_TYPE_SET_ATTRIBUTE)
expect(addEventListenerAction[1]).toBe(2)
expect(addEventListenerAction[2]).toBe('.e0')
expect(addEventListenerAction[3]).toBe(1)
root.updateActions.length = 0
textNode.removeEventListener('click', clickFn)
const {
updateActions: [removeEventListenerAction],
} = root
expect(removeEventListenerAction[0]).toBe(ACTION_TYPE_REMOVE_ATTRIBUTE)
expect(removeEventListenerAction[1]).toBe(2)
expect(removeEventListenerAction[2]).toBe('.e0')
})
})
import {
ref,
nextTick,
createApp,
createVNode as _createVNode,
openBlock as _openBlock,
createBlock as _createBlock,
createCommentVNode as _createCommentVNode,
} from '../../../uni-app-vue/lib/service.runtime.esm'
import { createPageNode } from '../../src/service/framework/dom/Page'
const defaultPageNodeOptions = {
version: 1,
locale: 'zh_CN',
disableScroll: false,
onPageScroll: false,
onPageReachBottom: false,
onReachBottomDistance: 50,
statusbarHeight: 24,
windowTop: 0,
windowBottom: 0,
}
describe('vue', () => {
test('vdom', () => {
const show = ref(true)
let handleClick: Function | null = () => {}
const Page = {
setup() {
return () => {
return (
_openBlock(),
_createBlock(
'view',
{ class: 'a', onClick: handleClick },
[
show.value
? (_openBlock(),
_createBlock(
'view',
{
key: 0,
style: { color: 'red' },
},
'123'
))
: _createCommentVNode('v-if', true),
],
8 /* PROPS */,
['onClick']
)
)
}
},
}
const pageNode = createPageNode(1, defaultPageNodeOptions, true)
createApp(Page).mount(pageNode as unknown as Element)
pageNode.mounted()
show.value = false
handleClick = null
nextTick(() => {
pageNode.update()
})
})
})
......@@ -850,10 +850,10 @@
const isIntegerKey = (key) => isString$1(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key;
const isReservedProp = /* @__PURE__ */ makeMap(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted");
const cacheStringFunction$1 = (fn) => {
const cache = Object.create(null);
const cache2 = Object.create(null);
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
const hit = cache2[str];
return hit || (cache2[str] = fn(str));
};
};
const camelizeRE = /-(\w)/g;
......@@ -1895,8 +1895,8 @@
}
}
function normalizeEmitsOptions(comp, appContext, asMixin = false) {
const cache = appContext.emitsCache;
const cached = cache.get(comp);
const cache2 = appContext.emitsCache;
const cached = cache2.get(comp);
if (cached !== void 0) {
return cached;
}
......@@ -1922,7 +1922,7 @@
}
}
if (!raw && !hasExtends) {
cache.set(comp, null);
cache2.set(comp, null);
return null;
}
if (isArray(raw)) {
......@@ -1930,7 +1930,7 @@
} else {
extend$1(normalized, raw);
}
cache.set(comp, normalized);
cache2.set(comp, normalized);
return normalized;
}
function isEmitListener(options, key) {
......@@ -2630,10 +2630,10 @@
const { mixins, extends: extendsOptions } = base;
const {
mixins: globalMixins,
optionsCache: cache,
optionsCache: cache2,
config: { optionMergeStrategies }
} = instance.appContext;
const cached = cache.get(base);
const cached = cache2.get(base);
let resolved;
if (cached) {
resolved = cached;
......@@ -2648,7 +2648,7 @@
}
mergeOptions(resolved, base, optionMergeStrategies);
}
cache.set(base, resolved);
cache2.set(base, resolved);
return resolved;
}
function mergeOptions(to, from, strats, asMixin = false) {
......@@ -2883,8 +2883,8 @@
return value;
}
function normalizePropsOptions(comp, appContext, asMixin = false) {
const cache = appContext.propsCache;
const cached = cache.get(comp);
const cache2 = appContext.propsCache;
const cached = cache2.get(comp);
if (cached) {
return cached;
}
......@@ -2911,7 +2911,7 @@
}
}
if (!raw && !hasExtends) {
cache.set(comp, EMPTY_ARR);
cache2.set(comp, EMPTY_ARR);
return EMPTY_ARR;
}
if (isArray(raw)) {
......@@ -2940,7 +2940,7 @@
}
}
const res = [normalized, needCastKeys];
cache.set(comp, res);
cache2.set(comp, res);
return res;
}
function validatePropName(key) {
......@@ -5303,13 +5303,16 @@
offsetLeft
};
}
const cacheStringFunction = (fn) => {
const cache = Object.create(null);
function cache(fn) {
const cache2 = Object.create(null);
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
const hit = cache2[str];
return hit || (cache2[str] = fn(str));
};
};
}
function cacheStringFunction(fn) {
return cache(fn);
}
const PRIMARY_COLOR = "#007aff";
const SCHEME_RE = /^([a-z-]+:)?\/\//i;
const DATA_RE = /^data:.*,.*/;
......
......@@ -47,7 +47,7 @@ export function getRealPath(filepath: string) {
const normalizeLocalPath = cacheStringFunction((filepath: string) => {
return plus.io
.convertLocalFileSystemURL(filepath as any)
.convertLocalFileSystemURL(filepath)
.replace(/^\/?apps\//, '/android_asset/apps/')
.replace(/\/$/, '')
})
......
import {
UniNode,
NODE_TYPE_PAGE,
UniBaseNode,
IUniPageNode,
} from '@dcloudio/uni-shared'
const BRIDGE_NODE_SYNC = 'nodeSync'
const ACTION_TYPE_PAGE_CREATE = 1
const ACTION_TYPE_PAGE_CREATED = 2
export const ACTION_TYPE_CREATE = 3
export const ACTION_TYPE_INSERT = 4
export const ACTION_TYPE_REMOVE = 5
export const ACTION_TYPE_SET_ATTRIBUTE = 6
export const ACTION_TYPE_REMOVE_ATTRIBUTE = 7
export const ACTION_TYPE_SET_TEXT = 8
export interface PageNodeOptions {
version: number
locale: string
disableScroll: boolean
onPageScroll: boolean
onPageReachBottom: boolean
onReachBottomDistance: number
statusbarHeight: number
windowTop: number
windowBottom: number
}
interface PageCreateData extends PageNodeOptions {}
type PageCreateAction = [typeof ACTION_TYPE_PAGE_CREATE, PageCreateData]
type PageCreatedAction = [typeof ACTION_TYPE_PAGE_CREATED]
export type CreateAction = [
typeof ACTION_TYPE_CREATE,
number, // nodeId
string | number //nodeName
]
export type InsertAction = [
typeof ACTION_TYPE_INSERT,
number, // nodeId
number, // parentNodeId
number, // index
Record<string, any> // Element JSON
]
export type RemoveAction = [
typeof ACTION_TYPE_REMOVE,
number, // nodeId
number // parentNodeId
]
export type SetAttributeAction = [
typeof ACTION_TYPE_SET_ATTRIBUTE,
number, // nodeId
string, // attribute name
unknown // attribute value
]
export type RemoveAttributeAction = [
typeof ACTION_TYPE_REMOVE_ATTRIBUTE,
number, // nodeId
string // attribute name
]
export type SetTextAction = [
typeof ACTION_TYPE_SET_TEXT,
number, // nodeId
string // text content
]
type PageUpdateAction =
| CreateAction
| InsertAction
| RemoveAction
| SetAttributeAction
| RemoveAttributeAction
| SetTextAction
export type PageAction = PageCreateAction | PageCreatedAction | PageUpdateAction
export default class UniPageNode extends UniNode implements IUniPageNode {
pageId: number
private _id: number = 1
private createAction: PageCreateAction
private createdAction: PageCreatedAction
public updateActions: PageAction[] = []
constructor(
pageId: number,
options: PageNodeOptions,
setup: boolean = false
) {
super(NODE_TYPE_PAGE, '#page', null as unknown as IUniPageNode)
this.nodeId = 0
this.pageId = pageId
this.pageNode = this
this.createAction = [ACTION_TYPE_PAGE_CREATE, options]
this.createdAction = [ACTION_TYPE_PAGE_CREATED]
setup && this.setup()
}
onCreate(thisNode: UniNode, nodeName: string | number) {
pushCreateAction(this, thisNode.nodeId!, nodeName)
return thisNode
}
onInsertBefore(thisNode: UniNode, newChild: UniNode, index: number) {
pushInsertAction(this, newChild as UniBaseNode, thisNode.nodeId!, index)
return newChild
}
onRemoveChild(thisNode: UniNode, oldChild: UniNode) {
pushRemoveAction(this, oldChild.nodeId!, thisNode.nodeId!)
return oldChild
}
onSetAttribute(thisNode: UniNode, qualifiedName: string, value: unknown) {
if (thisNode.parentNode) {
pushSetAttributeAction(this, thisNode.nodeId!, qualifiedName, value)
}
}
onRemoveAttribute(thisNode: UniNode, qualifiedName: string) {
if (thisNode.parentNode) {
pushRemoveAttributeAction(this, thisNode.nodeId!, qualifiedName)
}
}
onTextContent(thisNode: UniNode, text: string) {
if (thisNode.parentNode) {
pushSetTextAction(this, thisNode.nodeId!, text)
}
}
onNodeValue(thisNode: UniNode, val: string | null) {
if (thisNode.parentNode) {
pushSetTextAction(this, thisNode.nodeId!, val as string)
}
}
genId() {
return this._id++
}
push(action: PageAction) {
this.updateActions.push(action)
}
restore() {
this.push(this.createAction)
// TODO restore children
this.push(this.createdAction)
}
setup() {
this.send([this.createAction])
}
mounted() {
const { updateActions, createdAction } = this
updateActions.unshift(createdAction)
this.update()
}
update() {
const { updateActions } = this
if (updateActions.length) {
this.send(updateActions)
updateActions.length = 0
}
}
send(action: PageAction[]) {
UniServiceJSBridge.publishHandler(BRIDGE_NODE_SYNC, action, this.pageId)
}
}
function pushCreateAction(
pageNode: UniPageNode,
nodeId: number,
nodeName: string | number
) {
pageNode.push([ACTION_TYPE_CREATE, nodeId, nodeName])
}
function pushInsertAction(
pageNode: UniPageNode,
newChild: UniBaseNode,
parentNodeId: number,
index: number
) {
pageNode.push([
ACTION_TYPE_INSERT,
newChild.nodeId!,
parentNodeId,
index,
newChild.toJSON({ attr: true }),
])
}
function pushRemoveAction(
pageNode: UniPageNode,
nodeId: number,
parentNodeId: number
) {
pageNode.push([ACTION_TYPE_REMOVE, nodeId, parentNodeId])
}
function pushSetAttributeAction(
pageNode: UniPageNode,
nodeId: number,
name: string,
value: unknown
) {
pageNode.push([ACTION_TYPE_SET_ATTRIBUTE, nodeId, name, value])
}
function pushRemoveAttributeAction(
pageNode: UniPageNode,
nodeId: number,
name: string
) {
pageNode.push([ACTION_TYPE_REMOVE_ATTRIBUTE, nodeId, name])
}
function pushSetTextAction(
pageNode: UniPageNode,
nodeId: number,
text: string
) {
pageNode.push([ACTION_TYPE_SET_TEXT, nodeId, text])
}
export function createPageNode(
pageId: number,
pageOptions: PageNodeOptions,
setup?: boolean
) {
return new UniPageNode(pageId, pageOptions, setup)
}
import { decodeTag } from '@dcloudio/uni-shared'
import {
CreateAction,
InsertAction,
RemoveAction,
SetAttributeAction,
RemoveAttributeAction,
SetTextAction,
ACTION_TYPE_CREATE,
ACTION_TYPE_INSERT,
ACTION_TYPE_REMOVE,
ACTION_TYPE_SET_ATTRIBUTE,
ACTION_TYPE_REMOVE_ATTRIBUTE,
ACTION_TYPE_SET_TEXT,
PageAction,
} from './Page'
function decodeCreateAction([, nodeId, nodeName]: CreateAction) {
return ['create', nodeId, decodeTag(nodeName)]
}
function decodeInsertAction([, ...action]: InsertAction) {
return ['insert', ...action]
}
function decodeRemoveAction([, ...action]: RemoveAction) {
return ['remove', ...action]
}
function decodeSetAttributeAction([, ...action]: SetAttributeAction) {
return ['setAttr', ...action]
}
function decodeRemoveAttributeAction([, ...action]: RemoveAttributeAction) {
return ['removeAttr', ...action]
}
function decodeSetTextAction([, ...action]: SetTextAction) {
return ['setText', action]
}
export function decodeActions(actions: PageAction[]) {
return actions.map((action) => {
switch (action[0]) {
case ACTION_TYPE_CREATE:
return decodeCreateAction(action)
case ACTION_TYPE_INSERT:
return decodeInsertAction(action)
case ACTION_TYPE_REMOVE:
return decodeRemoveAction(action)
case ACTION_TYPE_SET_ATTRIBUTE:
return decodeSetAttributeAction(action)
case ACTION_TYPE_REMOVE_ATTRIBUTE:
return decodeRemoveAttributeAction(action)
case ACTION_TYPE_SET_TEXT:
return decodeSetTextAction(action)
}
return action
})
}
import { once } from '@dcloudio/uni-shared'
import { createApp, defineComponent } from 'vue'
import { createPageNode, PageNodeOptions } from '../dom/Page'
import { setupPage } from './setup'
export type VueComponent = ReturnType<typeof defineComponent>
const pagesMap = new Map<string, ReturnType<typeof createFactory>>()
export function definePage(pagePath: string, component: VueComponent) {
pagesMap.set(pagePath, once(createFactory(component)))
}
export function createPage(
pageId: number,
pagePath: string,
pageQuery: Record<string, any>,
pageInstance: unknown,
pageOptions: PageNodeOptions
) {
return createApp(pagesMap.get(pagePath)!(), {
pagePath,
pageQuery,
pageInstance,
}).mount(createPageNode(pageId, pageOptions) as unknown as Element)
}
function createFactory(component: VueComponent) {
return () => {
return setupPage(component)
}
}
import { initEntry } from '../app/initEntry'
import { initRouteOptions } from './initRouteOptions'
import { createWebview } from './webview'
export type OpenType =
| 'navigateTo'
| 'redirectTo'
| 'reLaunch'
| 'switchTab'
| 'navigateBack'
| 'preloadPage'
interface RegisterPageOptions {
url: string
path: string
query: Record<string, string>
openType: OpenType
webview?: PlusWebviewWebviewObject
eventChannel: unknown
}
export function registerPage({
path,
query,
openType,
webview,
}: RegisterPageOptions) {
// fast 模式,nvue 首页时,会在nvue中主动调用registerPage并传入首页webview,此时初始化一下首页(因为此时可能还未调用registerApp)
if (webview) {
initEntry()
}
// TODO preloadWebview
const routeOptions = initRouteOptions(path, openType)
if (!webview) {
webview = createWebview({ path, routeOptions, query })
} else {
webview = plus.webview.getWebviewById(webview.id)
;(webview as any).nvue = routeOptions.meta.isNVue
}
if (__DEV__) {
console.log(`[uni-app] registerPage(${path},${webview.id})`)
}
}
export * from './define'
export * from './register'
plus.webview.create
import { hasOwn } from '@vue/shared'
import { NAVBAR_HEIGHT, ON_REACH_BOTTOM_DISTANCE } from '@dcloudio/uni-shared'
import { initEntry } from '../app/initEntry'
import { initRouteOptions } from './initRouteOptions'
import { createWebview } from './webview'
import { createPage } from './define'
import { PageNodeOptions } from '../dom/Page'
import { getStatusbarHeight } from '../../../helpers/statusBar'
import tabBar from '../app/tabBar'
export type OpenType =
| 'navigateTo'
| 'redirectTo'
| 'reLaunch'
| 'switchTab'
| 'navigateBack'
| 'preloadPage'
interface RegisterPageOptions {
url: string
path: string
query: Record<string, string>
openType: OpenType
webview?: PlusWebviewWebviewObject
eventChannel: unknown
}
export function registerPage({
path,
query,
openType,
webview,
}: RegisterPageOptions) {
// fast 模式,nvue 首页时,会在nvue中主动调用registerPage并传入首页webview,此时初始化一下首页(因为此时可能还未调用registerApp)
if (webview) {
initEntry()
}
// TODO preloadWebview
const routeOptions = initRouteOptions(path, openType)
if (!webview) {
webview = createWebview({ path, routeOptions, query })
} else {
webview = plus.webview.getWebviewById(webview.id)
;(webview as any).nvue = routeOptions.meta.isNVue
}
if (__DEV__) {
console.log(`[uni-app] registerPage(${path},${webview.id})`)
}
const route = path.substr(1)
if (!(webview as any).nvue) {
createPage(
parseInt(webview.id!),
route,
query,
null,
initPageOptions(routeOptions)
)
}
}
function initPageOptions({ meta }: UniApp.UniRoute): PageNodeOptions {
const statusbarHeight = getStatusbarHeight()
return {
version: 1,
locale: '',
disableScroll: meta.disableScroll === true,
onPageScroll: false,
onPageReachBottom: false,
onReachBottomDistance: hasOwn(meta, 'onReachBottomDistance')
? meta.onReachBottomDistance!
: ON_REACH_BOTTOM_DISTANCE,
statusbarHeight,
windowTop:
meta.navigationBar.type === 'float' ? statusbarHeight + NAVBAR_HEIGHT : 0,
windowBottom:
tabBar.indexOf(meta.route) >= 0 && tabBar.cover ? tabBar.height : 0,
}
}
import { VueComponent } from './define'
export function setupPage(component: VueComponent) {
return component
}
import * as uni from './api'
import { registerApp as __registerApp } from './framework/app'
import { registerPage as __registerPage } from './framework/page'
import {
definePage as __definePage,
registerPage as __registerPage,
} from './framework/page'
// ;(uni as any).__$wx__ = uni
export default {
uni,
__definePage,
__registerApp,
__registerPage,
}
import {
decodeTag,
UniNode,
NODE_TYPE_PAGE,
UniElement,
UniTextNode,
UniCommentNode,
} from '@dcloudio/uni-shared'
import { UniElement, UniTextNode, UniCommentNode } from '@dcloudio/uni-shared'
/**
* Make a map and return a function for checking if a key
......@@ -10361,155 +10354,6 @@ const resolveFilter = null
*/
const compatUtils = null
const BRIDGE_NODE_SYNC = 'nodeSync'
const ACTION_TYPE_PAGE_CREATE = 1
const ACTION_TYPE_PAGE_CREATED = 2
const ACTION_TYPE_CREATE = 3
const ACTION_TYPE_INSERT = 4
const ACTION_TYPE_REMOVE = 5
const ACTION_TYPE_SET_ATTRIBUTE = 6
const ACTION_TYPE_REMOVE_ATTRIBUTE = 7
const ACTION_TYPE_SET_TEXT = 8
function decodeCreateAction([, nodeId, nodeName]) {
return ['create', nodeId, decodeTag(nodeName)]
}
function decodeInsertAction([, ...action]) {
return ['insert', ...action]
}
function decodeRemoveAction([, ...action]) {
return ['remove', ...action]
}
function decodeSetAttributeAction([, ...action]) {
return ['setAttr', ...action]
}
function decodeRemoveAttributeAction([, ...action]) {
return ['removeAttr', ...action]
}
function decodeSetTextAction([, ...action]) {
return ['setText', action]
}
function decodeActions(actions) {
return actions.map((action) => {
switch (action[0]) {
case ACTION_TYPE_CREATE:
return decodeCreateAction(action)
case ACTION_TYPE_INSERT:
return decodeInsertAction(action)
case ACTION_TYPE_REMOVE:
return decodeRemoveAction(action)
case ACTION_TYPE_SET_ATTRIBUTE:
return decodeSetAttributeAction(action)
case ACTION_TYPE_REMOVE_ATTRIBUTE:
return decodeRemoveAttributeAction(action)
case ACTION_TYPE_SET_TEXT:
return decodeSetTextAction(action)
}
return action
})
}
class UniPageNode extends UniNode {
constructor(pageId, options, setup = false) {
super(NODE_TYPE_PAGE, '#page', null)
this._id = 1
this.updateActions = []
this.nodeId = 0
this.pageId = pageId
this.pageNode = this
this.createAction = [ACTION_TYPE_PAGE_CREATE, options]
this.createdAction = [ACTION_TYPE_PAGE_CREATED]
setup && this.setup()
}
onCreate(thisNode, nodeName) {
pushCreateAction(this, thisNode.nodeId, nodeName)
return thisNode
}
onInsertBefore(thisNode, newChild, index) {
pushInsertAction(this, newChild, thisNode.nodeId, index)
return newChild
}
onRemoveChild(thisNode, oldChild) {
pushRemoveAction(this, oldChild.nodeId, thisNode.nodeId)
return oldChild
}
onSetAttribute(thisNode, qualifiedName, value) {
if (thisNode.parentNode) {
pushSetAttributeAction(this, thisNode.nodeId, qualifiedName, value)
}
}
onRemoveAttribute(thisNode, qualifiedName) {
if (thisNode.parentNode) {
pushRemoveAttributeAction(this, thisNode.nodeId, qualifiedName)
}
}
onTextContent(thisNode, text) {
if (thisNode.parentNode) {
pushSetTextAction(this, thisNode.nodeId, text)
}
}
onNodeValue(thisNode, val) {
if (thisNode.parentNode) {
pushSetTextAction(this, thisNode.nodeId, val)
}
}
genId() {
return this._id++
}
push(action) {
this.updateActions.push(action)
}
restore() {
this.push(this.createAction)
// TODO restore children
this.push(this.createdAction)
}
setup() {
this.send([this.createAction])
}
mounted() {
const { updateActions, createdAction } = this
updateActions.unshift(createdAction)
this.update()
}
update() {
const { updateActions } = this
if (updateActions.length) {
this.send(updateActions)
updateActions.length = 0
}
}
send(action) {
// @ts-expect-error
UniServiceJSBridge.publishHandler(BRIDGE_NODE_SYNC, action, this.pageId)
}
}
function pushCreateAction(pageNode, nodeId, nodeName) {
pageNode.push([ACTION_TYPE_CREATE, nodeId, nodeName])
}
function pushInsertAction(pageNode, newChild, parentNodeId, index) {
pageNode.push([
ACTION_TYPE_INSERT,
newChild.nodeId,
parentNodeId,
index,
newChild.toJSON({ attr: true }),
])
}
function pushRemoveAction(pageNode, nodeId, parentNodeId) {
pageNode.push([ACTION_TYPE_REMOVE, nodeId, parentNodeId])
}
function pushSetAttributeAction(pageNode, nodeId, name, value) {
pageNode.push([ACTION_TYPE_SET_ATTRIBUTE, nodeId, name, value])
}
function pushRemoveAttributeAction(pageNode, nodeId, name) {
pageNode.push([ACTION_TYPE_REMOVE_ATTRIBUTE, nodeId, name])
}
function pushSetTextAction(pageNode, nodeId, text) {
pageNode.push([ACTION_TYPE_SET_TEXT, nodeId, text])
}
function createPageNode(pageId, pageOptions, setup) {
return new UniPageNode(pageId, pageOptions, setup)
}
function createElement(tagName, container) {
return new UniElement(tagName, container)
}
......@@ -11357,7 +11201,6 @@ export {
createCommentVNode,
createElement,
createHydrationRenderer,
createPageNode,
createRenderer,
createSSRApp,
createSlots,
......@@ -11367,7 +11210,6 @@ export {
createVNode,
createApp as createVueApp,
customRef,
decodeActions,
defineAsyncComponent,
defineComponent,
defineEmit,
......
{
"private": true,
"name": "@dcloudio/uni-app-vue",
"version": "3.0.0-alpha-3000020210618002",
"description": "@dcloudio/uni-app-vue",
"main": "dist/vue.runtime.esm.js",
"module": "dist/vue.runtime.esm.js",
"files": [
"dist"
],
......
......@@ -73,3 +73,19 @@ export function invokeHook(
const hooks = vm.$[name as string]
return hooks && invokeArrayFns(hooks, args)
}
export function hasHook(vm: ComponentPublicInstance | number, name: string) {
if (typeof vm === 'number') {
const page = getCurrentPages().find((page) => page.$page.id === vm)
if (page) {
vm = (page as any).$vm as ComponentPublicInstance
} else {
vm = getCurrentPageVm() as ComponentPublicInstance
}
}
if (!vm) {
return false
}
const hooks = vm.$[name]
return !!(hooks && hooks.length)
}
......@@ -693,13 +693,16 @@ function decodeTag(tag) {
return DECODED_COMPONENT_ARR[tag] || tag;
}
const cacheStringFunction = (fn) => {
function cache(fn) {
const cache = Object.create(null);
return ((str) => {
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
});
};
};
}
function cacheStringFunction(fn) {
return cache(fn);
}
function getLen(str = '') {
return ('' + str).replace(/[^\x00-\xff]/g, '**').length;
}
......@@ -917,6 +920,7 @@ exports.UniTextAreaElement = UniTextAreaElement;
exports.UniTextNode = UniTextNode;
exports.WEB_INVOKE_APPSERVICE = WEB_INVOKE_APPSERVICE;
exports.addFont = addFont;
exports.cache = cache;
exports.cacheStringFunction = cacheStringFunction;
exports.callOptions = callOptions;
exports.createRpx2Unit = createRpx2Unit;
......
......@@ -6,7 +6,9 @@ export declare const BACKGROUND_COLOR = "#f7f7f7";
export declare const BUILT_IN_TAGS: string[];
export declare const cacheStringFunction: <T extends (str: string) => string>(fn: T) => T;
export declare function cache<T>(fn: (str: string) => T): (str: string) => T;
export declare function cacheStringFunction(fn: (string: string) => string): (str: string) => string;
export declare function callOptions(options: Options, errMsg: string): void;
......
......@@ -689,13 +689,16 @@ function decodeTag(tag) {
return DECODED_COMPONENT_ARR[tag] || tag;
}
const cacheStringFunction = (fn) => {
function cache(fn) {
const cache = Object.create(null);
return ((str) => {
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
});
};
};
}
function cacheStringFunction(fn) {
return cache(fn);
}
function getLen(str = '') {
return ('' + str).replace(/[^\x00-\xff]/g, '**').length;
}
......@@ -879,4 +882,4 @@ function getEnvLocale() {
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, 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, passive, plusReady, removeLeadingSlash, sanitise, scrollTo, stringifyQuery, updateElementStyle };
export const cacheStringFunction = <T extends (str: string) => string>(
fn: T
): T => {
const cache: Record<string, string> = Object.create(null)
return ((str: string) => {
export function cache<T>(fn: (str: string) => T) {
const cache: Record<string, T> = Object.create(null)
return (str: string) => {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}) as any
}
}
export function cacheStringFunction(fn: (string: string) => string) {
return cache<string>(fn)
}
export function getLen(str = '') {
......
;(global as any).UniServiceJSBridge = {
publishHandler(...args: any[]) {
console.log('publishHandler', JSON.stringify(args))
},
}
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册