2025/2/8第一次更新

This commit is contained in:
爱吃咸鱼小猫咪
2025-02-08 18:50:38 +08:00
commit d7af560866
26519 changed files with 5046029 additions and 0 deletions
@@ -0,0 +1,169 @@
// @ts-expect-error
import type { Callback } from '../../index.uts'
type SocketInstanceData = {
instance: SocketTask,
isOpend: boolean,
openData?: OnSocketOpenCallbackResult | null
}
const socketInstanceMap = new Map<string, SocketInstanceData>()
export const connectSocket = (id: string, url: string, callback: Callback): void => {
const socketTask = uni.connectSocket({
url,
success() {
callback({ result: { errMsg: 'connectSocket:ok' } }, null)
},
fail() {
callback(null, { errMsg: 'connectSocket:fail' })
}
})
socketInstanceMap.set(id, { instance: socketTask, isOpend: false } as SocketInstanceData)
socketTask.onOpen((data: OnSocketOpenCallbackResult) => {
socketInstanceMap.get(id)!.isOpend = true
socketInstanceMap.get(id)!.openData = data
})
}
export type FirstSocketTaskEmitterParams = {
method: string,
data?: any | null,
code?: number | null,
reason?: string | null,
}
export const firstSocketTaskEmitter = (params: FirstSocketTaskEmitterParams, callback: Callback): void => {
let socketInstanceData: SocketInstanceData | null = null;
socketInstanceMap.forEach((value: SocketInstanceData) => {
if (socketInstanceData == null) {
socketInstanceData = value
}
})
if (socketInstanceData == null) {
callback(null, { errMsg: "socketTask not exists." });
} else {
const _socketInstanceData = socketInstanceData as SocketInstanceData
const socketTask = _socketInstanceData.instance
if (params.method == 'onOpen') {
const isOpend = _socketInstanceData.isOpend
if (isOpend) {
callback(_socketInstanceData.openData, null)
} else {
let timer: number | null = null
// @ts-expect-error
timer = setInterval(() => {
if (_socketInstanceData.isOpend) {
clearInterval(timer!)
callback(_socketInstanceData.openData, null)
}
}, 200)
setTimeout(() => {
// @ts-expect-error
clearInterval(timer)
}, 2000)
}
} else if (params.method == 'onMessage') {
socketTask.onMessage((data: any) => {
callback(data, null)
})
} else if (params.method == 'onClose') {
socketTask.onClose((data: any) => {
callback(data, null)
})
} else if (params.method == 'onError') {
socketTask.onError((data: any) => {
callback(data, null)
})
} else if (params.method == 'send') {
socketTask.send({
data: params.data!,
success(result: any) {
callback({ result }, null)
},
fail(error: any) {
callback(null, error)
}
} as SendSocketMessageOptions)
} else if (params.method == 'close') {
socketTask.close({
code: params.code,
reason: params.reason,
success(result: any) {
callback({ result }, null)
socketInstanceMap.clear();
},
fail(error: any) {
callback(null, error)
}
} as CloseSocketOptions)
}
}
}
export type SocketEmitterParams = {
id: string,
method: string,
data?: any | null,
code?: number | null,
reason?: string | null,
}
export const socketEmitter = (params: SocketEmitterParams, callback: Callback): void => {
if (!socketInstanceMap.has(params.id)) {
callback(null, { errMsg: 'socketTask not exists.' })
} else {
const socketInstanceData = socketInstanceMap.get(params.id)!
const socketTask = socketInstanceData.instance
if (params.method == 'onOpen') {
const isOpend = socketInstanceData.isOpend
if (isOpend) {
callback({ method: 'Socket.onOpen', id: params.id, data: socketInstanceData.openData }, null)
} else {
let timer: number | null = null
// @ts-expect-error
timer = setInterval(() => {
if (socketInstanceData.isOpend) {
clearInterval(timer!)
callback({ method: 'Socket.onOpen', id: params.id, data: socketInstanceData.openData }, null)
}
}, 200)
setTimeout(() => {
// @ts-expect-error
clearInterval(timer)
}, 2000)
}
} else if (params.method == 'onMessage') {
socketTask.onMessage((data: any) => {
callback({ method: 'Socket.onMessage', id: params.id, data }, null)
})
} else if (params.method == 'onClose') {
socketTask.onClose((data: any) => {
callback({ method: 'Socket.onClose', id: params.id, data }, null)
})
} else if (params.method == 'onError') {
socketTask.onError((data: any) => {
callback({ method: 'Socket.onError', id: params.id, data }, null)
})
} else if (params.method == 'send') {
socketTask.send({
data: params.data!,
success(result: any) {
callback(result, null)
},
fail(error: any) {
callback(null, error)
}
} as SendSocketMessageOptions)
} else if (params.method == 'close') {
socketTask.close({
code: params.code,
reason: params.reason,
success(result: any) {
callback(result, null)
socketInstanceMap.delete(params.id);
},
fail(error: any) {
callback(null, error)
}
} as CloseSocketOptions)
}
}
}
@@ -0,0 +1,459 @@
// @ts-expect-error
import type { Callback } from '../../index.uts'
// @ts-expect-error
import { parsePage } from '../util.uts'
// @ts-expect-error
import { send } from '../../index.uts'
import {
type FirstSocketTaskEmitterParams,
connectSocket,
firstSocketTaskEmitter,
// @ts-expect-error
} from './Socket.uts'
export const getPageStack = (callback: Callback): void => {
callback(
{
// @ts-expect-error
pageStack: getCurrentPages().map((page: UniPage): UTSJSONObject => {
return parsePage(page.vm!)
}),
},
null
)
}
export type GetCurrentPageParams = {
// @ts-expect-error
callback: (result: UTSJSONObject | null, error: any | null) => void
}
function _getCurrentPage(): Page | null {
const pages = getCurrentPages() as UniPage[]
return pages.length > 0 ? pages[pages.length - 1].vm! : null
}
export const getCurrentPage = (params: GetCurrentPageParams): void => {
const page = _getCurrentPage()
const result = page != null ? parsePage(page) : null
params.callback(result, null)
}
export type CallUniMethodParams = {
method: string
args: any[]
}
export const callUniMethod = (
params: CallUniMethodParams,
callback: Callback
): void => {
const method = params.method
const args = params.args
const success = (result: any) => {
const timeout = method == 'pageScrollTo' ? 350 : 0
setTimeout(() => {
callback({ result }, null)
}, timeout)
}
const onApiCallback = (data: any | null, _: any | null) => {
const id = args[0] as string
send({ id, result: { method, data } })
}
switch (method) {
case 'navigateTo':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.navigateTo({
url: _arg['url'] as string,
// @ts-expect-error
animationType:
_arg['animationType'] != null
? (_arg['animationType'] as string)
: 'pop-in',
animationDuration:
_arg['animationDuration'] != null
? (_arg['animationDuration'] as number)
: 300,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'redirectTo':
uni.redirectTo({
// @ts-expect-error
url: new UTSJSONObject(args[0])['url'] as string,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'reLaunch':
uni.reLaunch({
// @ts-expect-error
url: new UTSJSONObject(args[0])['url'] as string,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'navigateBack':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.navigateBack({
// @ts-expect-error
animationType:
_arg['animationType'] != null
? (_arg['animationType'] as string)
: 'pop-out',
animationDuration:
_arg['animationDuration'] != null
? (_arg['animationDuration'] as number)
: 300,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'switchTab':
uni.switchTab({
// @ts-expect-error
url: new UTSJSONObject(args[0])['url'] as string,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'getStorage':
uni.getStorage({
// @ts-expect-error
key: new UTSJSONObject(args[0])['key'] as string,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'setStorage':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.setStorage({
key: _arg['key'] as string,
data: _arg['data']!,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'getStorageSync':
callback({ result: uni.getStorageSync(args[0] as string) }, null)
break
case 'setStorageSync':
callback({ result: uni.setStorageSync(args[0] as string, args[1]) }, null)
break
case 'getStorageInfo':
uni.getStorageInfo({
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'getStorageInfoSync':
callback({ result: uni.getStorageInfoSync() }, null)
break
case 'removeStorage':
uni.removeStorage({
// @ts-expect-error
key: new UTSJSONObject(args[0])['key'] as string,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'removeStorageSync':
callback({ result: uni.removeStorageSync(args[0] as string) }, null)
break
case 'clearStorage':
// @ts-expect-error
uni.clearStorage({
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'clearStorageSync':
callback({ result: uni.clearStorageSync() }, null)
break
case 'showToast':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.showToast({
title: _arg['title'] as string,
// @ts-expect-error
icon: _arg['icon'] != null ? (_arg['icon'] as string) : 'success',
// @ts-expect-error
image:
_arg['image'] != null && _arg['image'] != ''
? (_arg['image'] as string)
: null,
mask: _arg['mask'] != null ? (_arg['mask'] as boolean) : false,
duration:
_arg['duration'] != null ? (_arg['duration'] as number) : 1500,
// @ts-expect-error
position:
_arg['position'] != null ? (_arg['position'] as string) : null,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'hideToast':
uni.hideToast()
break
case 'showLoading':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.showLoading({
title: _arg['title'] as string,
mask: _arg['mask'] != null ? (_arg['mask'] as boolean) : false,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'hideLoading':
uni.hideLoading()
break
case 'showModal':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.showModal({
// @ts-expect-error
title: _arg['title'] != null ? (_arg['title'] as string) : null,
// @ts-expect-error
content: _arg['content'] != null ? (_arg['content'] as string) : null,
showCancel:
_arg['showCancel'] != null ? (_arg['showCancel'] as boolean) : true,
// @ts-expect-error
cancelText:
_arg['cancelText'] != null ? (_arg['cancelText'] as string) : null,
// @ts-expect-error
cancelColor:
_arg['cancelColor'] != null ? (_arg['cancelColor'] as string) : null,
// @ts-expect-error
confirmText:
_arg['confirmText'] != null ? (_arg['confirmText'] as string) : null,
// @ts-expect-error
confirmColor:
_arg['confirmColor'] != null
? (_arg['confirmColor'] as string)
: null,
editable:
_arg['editable'] != null ? (_arg['editable'] as boolean) : false,
// @ts-expect-error
placeholderText:
_arg['placeholderText'] != null
? (_arg['placeholderText'] as string)
: null,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'showActionSheet':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.showActionSheet({
// @ts-expect-error
title: _arg['title'] != null ? (_arg['title'] as string) : null,
// @ts-expect-error
itemList: JSON.parse<string[]>(JSON.stringify(_arg['itemList']))!,
// @ts-expect-error
itemColor:
_arg['itemColor'] != null ? (_arg['itemColor'] as string) : null,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'connectSocket':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
connectSocket(_arg['id'] as string, _arg['url'] as string, callback)
break
case 'onSocketOpen':
firstSocketTaskEmitter(
{ method: 'onOpen' } as FirstSocketTaskEmitterParams,
onApiCallback
)
break
case 'onSocketMessage':
firstSocketTaskEmitter(
{ method: 'onMessage' } as FirstSocketTaskEmitterParams,
onApiCallback
)
break
case 'onSocketError':
firstSocketTaskEmitter(
{ method: 'onError' } as FirstSocketTaskEmitterParams,
onApiCallback
)
break
case 'onSocketClose':
firstSocketTaskEmitter(
{ method: 'onClose' } as FirstSocketTaskEmitterParams,
onApiCallback
)
break
case 'sendSocketMessage':
firstSocketTaskEmitter(
{
method: 'send',
// @ts-expect-error
data: new UTSJSONObject(args[0])['data'],
} as FirstSocketTaskEmitterParams,
callback
)
break
case 'closeSocket':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
firstSocketTaskEmitter(
{
method: 'close',
code: _arg['code'] as number,
reason: _arg['reason'] as string,
} as FirstSocketTaskEmitterParams,
callback
)
break
case 'getSystemInfo':
uni.getSystemInfo({
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'getSystemInfoSync':
callback({ result: uni.getSystemInfoSync() }, null)
break
case 'getDeviceInfo':
callback({ result: uni.getDeviceInfo() }, null)
break
case 'getSystemSetting':
callback({ result: uni.getSystemSetting() }, null)
break
case 'getAppBaseInfo':
callback({ result: uni.getAppBaseInfo() }, null)
break
case 'getAppAuthorizeSetting':
callback({ result: uni.getAppAuthorizeSetting() }, null)
break
case 'openAppAuthorizeSetting':
uni.openAppAuthorizeSetting({
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
case 'pageScrollTo':
// @ts-expect-error
const _arg = new UTSJSONObject(args[0])
uni.pageScrollTo({
scrollTop: _arg['scrollTop'] as number,
duration: _arg['duration'] as number,
success,
fail(error) {
error.errMsg = error.errMsg.replace(`${method}: fail `, '')
callback(null, error)
},
})
break
default:
callback(null, { errMsg: 'uni.' + method + ' not exists.' })
break
}
}
export type CaptureScreenshotParams = {
id?: string | null
fullPage?: boolean | null
path?: string | null
offsetX?: string | null
offsetY?: string | null
}
export const captureScreenshot = (
params: CaptureScreenshotParams,
callback: Callback
): void => {
const currentPage = _getCurrentPage()
if (currentPage != null) {
// @ts-expect-error
currentPage.$viewToTempFilePath({
id: params.id,
offsetX: params.offsetX !== null ? params.offsetX : '0',
offsetY: params.offsetY !== null ? params.offsetY : '0',
wholeContent: params.fullPage == true,
path: params.path,
success: (res) => {
const fileManager = uni.getFileSystemManager()
// @ts-expect-error
fileManager.readFile({
encoding: 'base64',
filePath: res.tempFilePath,
success(readFileRes) {
callback(
{
errMsg: 'screenshot:ok',
tempFilePath: res.tempFilePath,
data: readFileRes.data,
},
null
)
},
fail(error) {
callback(null, error)
},
} as ReadFileOptions)
},
fail: (error) => {
callback(null, error)
},
})
} else {
callback(null, { errMsg: `currentPage is not found.` })
}
}
@@ -0,0 +1,644 @@
// @ts-expect-error
import type { Callback } from '../index.uts'
import {
componentGetData,
componentSetData,
getComponentVmByNodeId,
getComponentVmBySelector,
getElementById,
getElementByIdOrNodeId,
getElementByNodeIdOrElementId,
getValidNodes,
removeUniPrefix,
// @ts-expect-error
} from './util.uts'
// @ts-expect-error
import { getChildrenText, toCamelCase } from './util.uts'
export type GetElementParams = {
pageId: string
nodeId?: number | null
elementId?: string | null
selector: string
}
export const getElement = (
params: GetElementParams,
callback: Callback
): void => {
// TODO: support get component by class or id selector
const element = getElementByNodeIdOrElementId(
params.pageId,
params.nodeId,
params.elementId,
callback
)
if (element != null) {
if (params.selector.startsWith('uni-')) {
const selector = removeUniPrefix(params.selector)
const component = getComponentVmBySelector(
params.pageId,
selector,
callback
)
const result = {
nodeId: component != null ? component.$.uid : null,
tagName: component != null ? selector : null,
elementId: component != null ? `${Date.now()}` : null,
}
callback(result, null)
return
}
// @ts-expect-error
const list: UTSJSONObject[] = []
getValidNodes(element, params.selector, list)
if (list.length > 0) {
callback(list[0], null)
} else {
callback(null, { errMsg: `Element[${params.selector}] not exists` })
}
}
}
export const getElements = (
params: GetElementParams,
callback: Callback
): void => {
const element = getElementByNodeIdOrElementId(
params.pageId,
params.nodeId,
params.elementId,
callback
)
if (element != null) {
// @ts-expect-error
const list: UTSJSONObject[] = []
getValidNodes(element, removeUniPrefix(params.selector), list, true)
callback({ elements: list }, null)
}
}
export type GetDOMPropertiesParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
names: string[]
}
export const getDOMProperties = (
params: GetDOMPropertiesParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const properties = params.names.map((name: string): any | null => {
if (name == 'innerText') {
// @ts-expect-error
if (isTextElement(dom)) {
return dom.getAttribute('value')
} else {
return getChildrenText(dom)
}
}
if (name == 'value') {
return dom.getAttribute('value')
}
if (name == 'offsetWidth') {
return dom.offsetWidth
}
if (name == 'offsetHeight') {
return dom.offsetHeight
}
return `Element.getDOMProperties not support ${name}`
})
callback({ properties }, null)
}
}
export type GetPropertiesParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
names: string[]
}
export const getProperties = (
params: GetPropertiesParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
// @ts-expect-error
let component: ComponentPublicInstance | null = null
if (params.nodeId != null) {
component = getComponentVmByNodeId(params.pageId, params.nodeId!, callback)
}
const properties = params.names.map((name: string): any | null => {
if (component != null && component.$props[toCamelCase(name)] != null) {
return component.$props[toCamelCase(name)]
}
if (dom != null) {
return dom.getAttribute(name)
}
return null
})
callback({ properties }, null)
}
export type GetAttributesParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
names: string[]
}
export const getAttributes = (
params: GetAttributesParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const attributes = params.names.map((name: string): any | null => {
if (name == 'class') {
return dom.classList.join(' ')
}
return dom.getAttribute(name)
})
callback({ attributes }, null)
}
}
export type CallFunctionParams = {
pageId: string
elementId: string
functionName: string
args: any[]
}
type Coordinate = {
x: number
y: number
}
export const callFunction = (
params: CallFunctionParams,
callback: Callback
): void => {
const element = getElementById(params.pageId, params.elementId, callback)
if (element != null) {
const functionName = params.functionName
switch (functionName) {
case 'input.input':
element.dispatchEvent(
'input',
new InputEvent(
'input',
// @ts-expect-error
InputEventDetail(params.args[0] as string, 0, 0)
)
)
callback({ result: `${functionName} success` }, null)
break
case 'textarea.input':
element.dispatchEvent(
'input',
new InputEvent(
'input',
// @ts-expect-error
InputEventDetail(params.args[0] as string, 0, 0)
)
)
callback({ result: `${functionName} success` }, null)
break
case 'scroll-view.scrollTo':
if (element.tagName == 'SCROLL-VIEW') {
const x: number = params.args[0] as number
const y: number = params.args[1] as number
element.scrollLeft = x
element.scrollTop = y
callback({ result: `${functionName} success` }, null)
} else {
callback(null, {
errMsg: `${functionName} fail, element is not scroll-view`,
})
}
break
case 'swiper.swipeTo':
if (element.tagName == 'SWIPER') {
callback(null, { errMsg: `${functionName} not support` })
} else {
callback(null, {
errMsg: `${functionName} fail, element is not swiper`,
})
return
}
break
case 'scroll-view.scrollWidth':
if (element.tagName == 'SCROLL-VIEW') {
callback({ result: element.scrollWidth }, null)
} else {
callback(null, {
errMsg: `${functionName} fail, element is not scroll-view`,
})
return
}
break
case 'scroll-view.scrollHeight':
if (element.tagName == 'SCROLL-VIEW') {
callback({ result: element.scrollHeight }, null)
} else {
callback(null, {
errMsg: `${functionName} fail, element is not scroll-view`,
})
return
}
break
case 'scroll-view.scrollTop':
if (element.tagName == 'SCROLL-VIEW') {
callback({ result: element.scrollTop }, null)
} else {
callback(null, {
errMsg: `${functionName} fail, element is not scroll-view`,
})
return
}
break
case 'scroll-view.scrollLeft':
if (element.tagName == 'SCROLL-VIEW') {
callback({ result: element.scrollLeft }, null)
} else {
callback(null, {
errMsg: `${functionName} fail, element is not scroll-view`,
})
return
}
break
default:
callback(null, { errMsg: `${functionName} not support` })
break
}
} else {
callback(null, { errMsg: `Element not exists` })
}
}
export type TapParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
}
export const tap = (params: TapParams, callback: Callback): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const num = 0
// @ts-expect-error
const _float = num.toFloat()
dom.dispatchEvent(
'click',
new MouseEvent(
'click',
_float,
// @ts-expect-error
_float,
_float,
_float,
_float,
_float,
_float,
_float
)
)
callback({ result: `Element.tap success` }, null)
}
}
export type CallMethodParams = {
pageId: string
nodeId: number
method: string
args: any[]
}
export const callMethod = (
params: CallMethodParams,
callback: Callback
): void => {
const component = getComponentVmByNodeId(
params.pageId,
params.nodeId,
callback
)
if (component != null) {
const result =
params.args.length > 0
? component.$callMethod(params.method, params.args[0])
: component.$callMethod(params.method)
// @ts-expect-error
if (result instanceof Promise<unknown>) {
; (result as Promise<any>)
.then((res: any) => {
callback({ result: res }, null)
})
.catch((err) => {
const errMsg = err instanceof Error ? err.message : err
callback({ result: errMsg }, null)
})
} else {
callback({ result }, null)
}
}
}
export type GetDataParams = {
pageId: string
nodeId: number
path?: string | null
}
export const getData = (params: GetDataParams, callback: Callback): void => {
const component = getComponentVmByNodeId(
params.pageId,
params.nodeId,
callback
)
if (component != null) {
const data = componentGetData(component)
callback({ data }, null)
}
}
export type SetDataParams = {
pageId: string
nodeId: number
data: Map<string, any | null>
}
export const setData = (params: SetDataParams, callback: Callback): void => {
const component = getComponentVmByNodeId(
params.pageId,
params.nodeId,
callback
)
if (component != null) {
componentSetData(component, params.data)
callback({ result: { errMsg: 'Page.setData: ok.' } }, null)
}
}
export type GetOffsetParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
}
export const getOffset = (
params: GetOffsetParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
callback({ left: dom.offsetLeft, top: dom.offsetTop }, null)
}
}
export type LongpressParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
}
export const longpress = (
params: LongpressParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const x: number = 0
const y: number = 0
dom.dispatchEvent(
'longpress',
new TouchEvent(
null,
'longpress',
// @ts-expect-error
getTouches([
{
identifier: 1,
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
screenX: 0,
screenY: 0,
},
]),
getTouches([
{
identifier: 1,
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
screenX: 0,
screenY: 0,
},
])
)
)
callback({ result: `Element.longpress success` }, null)
}
}
export type HandleTouchEventParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
touches: any[]
changedTouches: any[]
}
export const handleTouchEvent = (
params: HandleTouchEventParams,
eventName: string,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const touches = getTouches(params.touches)
const changedTouches = getTouches(params.changedTouches)
dom.dispatchEvent(
eventName,
// @ts-expect-error
new TouchEvent(null, eventName, touches, changedTouches)
)
callback({ result: `Element.${eventName} success` }, null)
}
}
type TypeTouch = {
identifier: number
pageX: number
pageY: number
screenX?: number | null
screenY?: number | null
clientX?: number | null
clientY?: number | null
}
function getTouches(touches: any[]): Touch[] {
return touches.map((touch): Touch => {
// @ts-expect-error
const touchObj = JSON.parse<TypeTouch>(JSON.stringify(touch))!
// @ts-expect-error
const result = Touch()
result.identifier = touchObj.identifier.toFloat()
result.pageX = touchObj.pageX.toFloat()
result.pageY = touchObj.pageY.toFloat()
if (touchObj.screenX !== null) {
result.screenX = touchObj.screenX!.toFloat()
}
if (touchObj.screenY !== null) {
result.screenY = touchObj.screenY!.toFloat()
}
if (touchObj.clientX !== null) {
result.clientX = touchObj.clientX!.toFloat()
}
if (touchObj.clientY !== null) {
result.clientY = touchObj.clientY!.toFloat()
}
return result
})
}
export type GetStylesParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
names: string[]
}
export const getStyles = (
params: GetStylesParams,
callback: Callback
): void => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const styles = params.names.map((name: string): any | null => {
return dom.style.getPropertyValue(name)
})
callback({ styles }, null)
}
}
type CustomEventDetail = {
value?: string
}
export type TriggerEventParams = {
pageId: string
elementId?: string | null
nodeId?: number | null
type: string
detail?: CustomEventDetail | null
}
export const triggerEvent = (
params: TriggerEventParams,
callback: Callback
) => {
const dom = getElementByIdOrNodeId(
params.pageId,
params.elementId,
params.nodeId,
callback
)
if (dom != null) {
const tagName = dom.tagName.toLocaleLowerCase()
const type = params.type
const detail = params.detail
const functionName = `${tagName}.${type}`
switch (functionName) {
case 'input.input':
dom.dispatchEvent(
type,
new UniInputEvent(
type,
// @ts-expect-error
UniInputEventDetail(detail === null ? '' : detail.value!, 0, 0)
)
)
callback({ result: `${functionName} success` }, null)
break
case 'input.focus':
dom.dispatchEvent(
type,
new UniInputFocusEvent(
type,
new InputFocusEventDetail(300, '')
)
)
callback({ result: `${functionName} success` }, null)
break
case 'input.blur':
dom.dispatchEvent(
type,
new UniInputBlurEvent(
type,
new UniInputBlurEventDetail('', 10)
)
)
callback({ result: `${functionName} success` }, null)
break
case 'textarea.input':
dom.dispatchEvent(
type,
new UniInputEvent(
type,
// @ts-expect-error
UniInputEventDetail(detail === null ? '' : detail.value!, 0, 0)
)
)
callback({ result: `${functionName} success` }, null)
break
}
callback(null, {
errMsg: `${functionName} not exists`,
})
}
}
+127
View File
@@ -0,0 +1,127 @@
// @ts-expect-error
import type { Callback } from '../index.uts'
// @ts-expect-error
import { getPageVm, getValidComponentsOrNodes, pageGetData, pageSetData, removeUniPrefix } from './util.uts'
export type GetDataParams = {
pageId: string
path?: string | null
}
export const getData = (params: GetDataParams, callback: Callback): void => {
const page = getPageVm(params.pageId)
if (page == null) {
callback(null, { errMsg: 'Page.getData:fail, Page not found.' })
return
}
const data = pageGetData(page)
callback({ data }, null)
}
export type SetDataParams = {
pageId: string
data: Map<string, any | null>
}
export const setData = (params: SetDataParams, callback: Callback): void => {
const pageId = params.pageId
const page = getPageVm(pageId)
if (page != null) {
pageSetData(page, params.data)
callback({ result: { errMsg: 'Page.setData: ok.' } }, null)
} else {
callback(null, { errMsg: `Page.setData:fail, Page:${pageId} is not found.` })
}
}
export type CallMethodParams = {
pageId: string
method: string
args: any[]
}
export const callMethod = (params: CallMethodParams, callback: Callback): void => {
const page = getPageVm(params.pageId)
if (page == null) {
callback(null, { errMsg: `Page[${params.pageId}] not exists` })
// @ts-expect-error
} else if (findVueMethod(page.$.type.type, params.method, page) == null) {
callback(null, { errMsg: `Page.${params.method} not exists` })
} else {
const result = params.args.length > 0 ? page.$callMethod(params.method, params.args[0]) : page.$callMethod(params.method)
// @ts-expect-error
if (result instanceof Promise<unknown>) {
(result as Promise<any>).then((res: any) => {
callback({ result: res }, null)
}).catch((err) => {
const errMsg = err instanceof Error ? err.message : err
callback({ result: errMsg }, null)
})
} else {
callback({ result }, null)
}
}
}
export type GetElementParams = {
pageId: string
selector: string
}
export const getElement = (params: GetElementParams, callback: Callback): void => {
const page = getPageVm(params.pageId)
if (page == null) {
callback(null, { errMsg: `Page[${params.pageId}] not exists` })
} else {
// @ts-expect-error
const list: UTSJSONObject[] = []
getValidComponentsOrNodes(page.$.subTree, removeUniPrefix(params.selector), list)
if (list.length > 0) {
callback(list[0], null)
} else {
callback(null, { errMsg: `Element[${params.selector}] not exists` })
}
}
}
export const getElements = (params: GetElementParams, callback: Callback): void => {
const page = getPageVm(params.pageId)
if (page == null) {
callback(null, { errMsg: `Page[${params.pageId}] not exists` })
} else {
const elements = page.$querySelectorAll(removeUniPrefix(params.selector))
// @ts-expect-error
const result = [] as UTSJSONObject[]
elements?.forEach(element => {
result.push({
elementId: element.getNodeId(),
tagName: element.tagName
})
})
callback({ elements: result }, null)
}
}
export type GetWindowPropertiesParams = {
pageId: string,
names: string[]
}
export const getWindowProperties = (params: GetWindowPropertiesParams, callback: Callback): void => {
const page = getPageVm(params.pageId)
if (page == null) {
callback(null, { errMsg: 'Page.getWindowProperties:fail, Page not found.' })
return
}
const document = page.$nativePage!.document
const rootNode = document.childNodes[0]
const properties = params.names.map((name): any | null => {
switch (name) {
case 'document.documentElement.scrollWidth':
return rootNode.scrollWidth
case 'document.documentElement.scrollHeight':
return rootNode.scrollHeight
case 'document.documentElement.scrollTop':
return rootNode.scrollTop
}
return null
})
callback({ properties }, null)
}
+323
View File
@@ -0,0 +1,323 @@
/// <reference types="@dcloudio/uni-app-x/types/native-global" />
/// <reference types="@dcloudio/uni-app-x/types/page" />
// @ts-expect-error
import type { IUniNativeDocument } from 'io.dcloud.uniapp.dom'
function getPageId(page: Page): string {
return page.$nativePage!.pageId
}
function getPagePath(page: Page): string {
return page.route
}
// @ts-expect-error
function getPageQuery(page: Page): UTSJSONObject {
return page.options
}
function getPageById(id: string): Page | null {
const pages = getCurrentPages() as UniPage[]
let result: Page | null = null
pages.forEach((page: UniPage) => {
if (getPageId(page.vm!) == id) {
result = page.vm!
}
})
return result
}
export function getPageVm(id: string): Page | null {
return getPageById(id)
}
export function pageGetData(
vm: Page
// @ts-expect-error
): UTSJSONObject {
// TODO: path 目前无法处理类型问题,暂由服务端处理
// @ts-expect-error
if (vm.$.exposed.size > 0) {
// @ts-expect-error
return new UTSJSONObject(vm.$.exposed)
}
// @ts-expect-error
return new UTSJSONObject(vm.$data)
}
export function pageSetData(vm: Page, data: Map<string, any | null>): void {
data.forEach((value: any | null, key: string) => {
// @ts-expect-error
vm.$data.set(key, value)
})
}
// @ts-expect-error
export function parsePage(page: Page): UTSJSONObject {
return {
id: getPageId(page),
path: getPagePath(page),
query: getPageQuery(page),
// @ts-expect-error
} as UTSJSONObject
}
export function getComponentVmBySelector(
pageId: string,
selector: string,
callback: (result: any | null, error: any | null) => void
// @ts-expect-error
): ComponentPublicInstance | null {
const page = getPageVm(pageId)
if (page == null) {
callback(null, { errMsg: `Page[${pageId}] not exists` })
return null
}
// @ts-expect-error
const component = page.$children.find(
// @ts-expect-error
(child: ComponentPublicInstance): boolean => child.$options.name == selector
)
if (component == null) {
callback(null, { errMsg: `component[${selector}] not exists` })
return null
}
return component
}
export function getComponentVmByNodeId(
pageId: string,
nodeId: number,
callback: (result: any | null, error: any | null) => void
// @ts-expect-error
): ComponentPublicInstance | null {
const page = getPageVm(pageId)
if (page == null) {
callback(null, { errMsg: `Page[${pageId}] not exists` })
return null
}
// @ts-expect-error
let component: ComponentPublicInstance | null = null
// @ts-expect-error
function getComponentChild(parent: ComponentPublicInstance) {
// @ts-expect-error
if (parent.$.uid.toInt() == nodeId.toInt()) {
component = parent
return
}
// @ts-expect-error
parent.$children.forEach((child: ComponentPublicInstance) => {
getComponentChild(child)
})
}
getComponentChild(page)
if (component == null) {
callback(null, { errMsg: `component[${nodeId}] not exists` })
return null
}
return component
}
export function getElementByIdOrNodeId(
pageId: string,
elementId: string | null,
nodeId: number | null,
callback: (result: any | null, error: any | null) => void
): UniElement | null {
if (nodeId != null) {
return getComponentDomByNodeId(pageId, nodeId, callback)
} else if (elementId != null) {
return getElementById(pageId, elementId, callback)
}
return null
}
export function getComponentDomByNodeId(
pageId: string,
nodeId: number,
callback: (result: any | null, error: any | null) => void
): UniElement | null {
const component = getComponentVmByNodeId(pageId, nodeId, callback)
if (component == null) {
return null
}
return component.$el
}
export function getElementByNodeIdOrElementId(
pageId: string,
nodeId: number | null,
elementId: string | null,
callback: (result: any | null, error: any | null) => void
): UniElement | null {
const page = getPageVm(pageId)
if (page == null) {
callback(null, { errMsg: `Page[${pageId}] not exists` })
return null
}
if (nodeId != null) {
return getComponentDomByNodeId(pageId, nodeId, callback)
} else if (elementId != null) {
return getElementById(pageId, elementId, callback)
}
return null
}
export function getElementById(
pageId: string,
elementId: string,
callback: (result: any | null, error: any | null) => void
): UniElement | null {
const page = getPageVm(pageId)
if (page == null) {
callback(null, { errMsg: `Page[${pageId}] not exists` })
return null
}
const document = page.$nativePage!.document
const element = (document as IUniNativeDocument).getNativeElementById(
elementId
)
if (element == null) {
callback(null, { errMsg: `element[${elementId}] not exists` })
return null
}
return element
}
export function getValidComponentsOrNodes(
// @ts-expect-error
vnode: VNode | null,
selector: string,
// @ts-expect-error
list: UTSJSONObject[],
getAll = false
): void {
if (vnode == null || (!getAll && list.length > 0)) {
return
}
if (isValidComponentOrNode(vnode, selector)) {
if (vnode.component != null) {
list.push({
// @ts-expect-error
nodeId: (vnode.component as ComponentInternalInstance).uid,
// @ts-expect-error
tagName: (vnode.component as ComponentInternalInstance).options.name,
elementId: `${Date.now()}`,
})
} else {
list.push({
// @ts-expect-error
elementId: (vnode.el as UniElementImpl).id,
tagName: vnode.el!.tagName,
})
}
if (!getAll) {
return
}
}
// @ts-expect-error
if (vnode.children !== null && isArray(vnode.children)) {
;(vnode.children as any[]).forEach((child) => {
// @ts-expect-error
if (child instanceof VNode) {
getValidComponentsOrNodes(child, selector, list, getAll)
}
})
}
if (vnode.component != null) {
const component = vnode.component
getValidComponentsOrNodes(component!.subTree, selector, list, getAll)
}
}
// @ts-expect-error
function isValidComponentOrNode(vnode: VNode, selector: string): boolean {
if (
vnode.component != null &&
// @ts-expect-error
(vnode.component as ComponentInternalInstance).options.name == selector
) {
return true
}
if (vnode.el != null) {
const node = vnode.el!
if (selector.startsWith('.')) {
return node.classList.includes(selector.substring(1))
} else if (selector.startsWith('#')) {
return node.getAttribute('id') == selector.substring(1)
}
return node.tagName.toUpperCase() == selector.toUpperCase()
}
return false
}
export function getValidNodes(
node: UniElement | null,
selector: string,
// @ts-expect-error
list: UTSJSONObject[],
getAll = false
): void {
if (node == null) {
return
}
if (isValidNode(node, selector)) {
list.push({
elementId: node.getNodeId(),
tagName: node.tagName,
})
if (!getAll) {
return
}
}
node.childNodes.forEach((child: UniElement) => {
getValidNodes(child, selector, list, getAll)
})
}
function isValidNode(node: UniElement, selector: string): boolean {
if (selector.startsWith('.')) {
return node.classList.includes(selector.substring(1))
} else if (selector.startsWith('#')) {
return node.getAttribute('id') == selector.substring(1)
}
return node.tagName.toUpperCase() == selector.toUpperCase()
}
export function componentGetData(
// @ts-expect-error
vm: ComponentPublicInstance
// @ts-expect-error
): UTSJSONObject {
// TODO: path 目前无法处理类型问题,暂由服务端处理
if (vm.$.exposed.size > 0) {
// @ts-expect-error
return new UTSJSONObject(vm.$.exposed)
}
// @ts-expect-error
return new UTSJSONObject(vm.$data)
}
export function componentSetData(
// @ts-expect-error
vm: ComponentPublicInstance,
data: Map<string, any | null>
): void {
data.forEach((value: any | null, key: string) => {
vm.$data.set(key, value)
})
}
export function getChildrenText(node: UniElement): string {
let result = ''
node.childNodes.forEach((child: UniElement) => {
// @ts-expect-error
if (isTextElement(child)) {
result += child.getAttribute('value')
} else {
result += getChildrenText(child)
}
})
return result
}
export function toCamelCase(str: string): string {
const wordList = str.split('-')
for (let i = 1; i < wordList.length; i++) {
const word = wordList[i]
wordList[i] = word.at(0)!.toUpperCase() + word.substring(1)
}
return wordList.join('')
}
export function removeUniPrefix(selector: string): string {
if (selector.startsWith("uni-")) {
return selector.replace("uni-", "");
}
return selector;
}