uview-plus 3.8.86 → 3.8.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +173 -3
- package/components/u-action-sheet/u-action-sheet.vue +21 -2
- package/components/u-barcode/u-barcode.vue +0 -2
- package/components/u-button/u-button.vue +2 -5
- package/components/u-canvas/u-canvas.vue +430 -77
- package/components/u-cell/u-cell.vue +8 -0
- package/components/u-datetime-picker/u-datetime-picker.vue +53 -4
- package/components/u-dragsort/u-dragsort.vue +55 -31
- package/components/u-icon/u-icon.vue +12 -3
- package/components/u-icon/util.js +81 -10
- package/components/u-index-item/u-index-item.vue +1 -1
- package/components/u-index-list/u-index-list.vue +1 -1
- package/components/u-novel-reader/content-normalizer.js +80 -0
- package/components/u-novel-reader/layout-engine.js +225 -0
- package/components/u-novel-reader/measure-adapter.js +69 -0
- package/components/u-novel-reader/novelReader.js +35 -0
- package/components/u-novel-reader/persistence.js +144 -0
- package/components/u-novel-reader/props.js +100 -0
- package/components/u-novel-reader/reader-catalog.vue +234 -0
- package/components/u-novel-reader/reader-content.vue +226 -0
- package/components/u-novel-reader/reader-core.js +151 -0
- package/components/u-novel-reader/reader-settings.vue +325 -0
- package/components/u-novel-reader/reader-toolbar.vue +313 -0
- package/components/u-novel-reader/theme-vars.scss +49 -0
- package/components/u-novel-reader/u-novel-reader.vue +836 -0
- package/components/u-poster/u-poster.vue +272 -222
- package/components/u-qrcode/qrcode.js +56 -49
- package/components/u-qrcode/u-qrcode.vue +159 -88
- package/components/u-scroll-list/scrollWxs.wxs +1 -1
- package/components/u-slider/u-slider.vue +1 -1
- package/components/u-swipe-action-item/index.wxs +43 -25
- package/components/u-swipe-action-item/nvue.js +9 -0
- package/components/u-swipe-action-item/other.js +32 -21
- package/components/u-swipe-action-item/props.js +5 -0
- package/components/u-swipe-action-item/swipeActionItem.js +1 -0
- package/components/u-swipe-action-item/u-swipe-action-item.vue +28 -4
- package/components/u-switch/u-switch.vue +1 -1
- package/components/u-tabbar/u-tabbar.vue +2 -1
- package/components/u-tabbar-item/u-tabbar-item.vue +64 -21
- package/components/u-tabs/u-tabs.vue +11 -8
- package/components/u-tabs-pro/u-tabs-pro.vue +212 -0
- package/components/u-text/text.js +1 -1
- package/components/u-text/u-text.vue +18 -6
- package/components/u-upload/u-upload.vue +1 -1
- package/components/u-waterfall/u-waterfall.vue +118 -65
- package/libs/config/config.js +1 -1
- package/libs/config/props.js +1 -0
- package/libs/function/index.js +66 -0
- package/libs/mixin/mixin.js +4 -50
- package/libs/root/index.js +78 -5
- package/libs/root/page.js +7 -7
- package/libs/root/root.js +73 -3
- package/libs/util/app-nvue-webview-canvas.js +486 -0
- package/libs/util/gcanvas/bridge/bridge-weex.js +0 -2
- package/libs/util/gcanvas/index.js +3 -3
- package/package.json +2 -2
- package/types/comps/swipeActionItem.d.ts +13 -0
- package/types/comps/tabs.d.ts +2 -1
- package/types/comps/text.d.ts +1 -1
- package/types/func.d.ts +23 -0
- package/types/index.d.ts +1 -0
package/libs/root/root.js
CHANGED
|
@@ -2,6 +2,28 @@ import { MagicString } from 'vue/compiler-sfc'
|
|
|
2
2
|
|
|
3
3
|
import { parseSFC } from './utils.js'
|
|
4
4
|
|
|
5
|
+
function ensureRootToastHostComponent(ms, scriptContent) {
|
|
6
|
+
const componentsMatch = scriptContent.match(/components\s*:\s*\{([\s\S]*?)\}/)
|
|
7
|
+
if (componentsMatch && /\bUpRootToastHost\b/.test(componentsMatch[1])) return
|
|
8
|
+
|
|
9
|
+
if (componentsMatch) {
|
|
10
|
+
ms.appendLeft(componentsMatch.index + componentsMatch[0].length, ' UpRootToastHost,')
|
|
11
|
+
return
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const exportDefaultMatch = scriptContent.match(/export\s+default\s+(?:defineComponent\s*\()?\s*\{/)
|
|
15
|
+
if (exportDefaultMatch) {
|
|
16
|
+
ms.appendLeft(
|
|
17
|
+
exportDefaultMatch.index + exportDefaultMatch[0].length,
|
|
18
|
+
'\n components: { UpRootToastHost },'
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getRootToastHostImport(importPath) {
|
|
24
|
+
return `import UpRootToastHost from '${importPath}'\n`
|
|
25
|
+
}
|
|
26
|
+
|
|
5
27
|
export async function registerUpApp(
|
|
6
28
|
code,
|
|
7
29
|
fileName = 'App.up',
|
|
@@ -21,17 +43,57 @@ import UpRootToastHost from "${rootToastHostPath}";`
|
|
|
21
43
|
return ms
|
|
22
44
|
}
|
|
23
45
|
|
|
24
|
-
export async function rebuildUpApp(
|
|
46
|
+
export async function rebuildUpApp(
|
|
47
|
+
code,
|
|
48
|
+
enabledVirtualHost = false,
|
|
49
|
+
{ rootToastHostImportPath = '' } = {}
|
|
50
|
+
) {
|
|
25
51
|
const ms = new MagicString(code)
|
|
26
52
|
const rootTagNameRE = /<(UpRootView|up-root-view)(?:\s*\/>|><\/\1>)/
|
|
27
|
-
|
|
53
|
+
const hasRootView = rootTagNameRE.test(code)
|
|
54
|
+
if (hasRootView) {
|
|
55
|
+
const rootToastHostTag = rootToastHostImportPath
|
|
56
|
+
? '<UpRootToastHost />'
|
|
57
|
+
: '<ku-root-toast-host />'
|
|
58
|
+
ms.replace(rootTagNameRE, `<slot />\n ${rootToastHostTag}`)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const shouldInjectRootToastHost = hasRootView && rootToastHostImportPath
|
|
62
|
+
const sfc = enabledVirtualHost || shouldInjectRootToastHost
|
|
63
|
+
? await parseSFC(code)
|
|
64
|
+
: null
|
|
65
|
+
|
|
66
|
+
if (shouldInjectRootToastHost) {
|
|
67
|
+
const importCode = getRootToastHostImport(rootToastHostImportPath)
|
|
68
|
+
|
|
69
|
+
if (sfc.scriptSetup) {
|
|
70
|
+
if (!/\bimport\s+UpRootToastHost\b/.test(sfc.scriptSetup.content)) {
|
|
71
|
+
ms.appendLeft(sfc.scriptSetup.loc.start.offset, importCode)
|
|
72
|
+
}
|
|
73
|
+
} else if (sfc.script) {
|
|
74
|
+
if (!/\bimport\s+UpRootToastHost\b/.test(sfc.script.content)) {
|
|
75
|
+
ms.appendLeft(sfc.script.loc.start.offset, importCode)
|
|
76
|
+
}
|
|
77
|
+
ensureRootToastHostComponent(ms, sfc.script.content)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
28
80
|
|
|
29
81
|
if (enabledVirtualHost) {
|
|
30
|
-
const sfc = await parseSFC(code)
|
|
31
82
|
if (sfc.script) {
|
|
32
83
|
return ms
|
|
33
84
|
}
|
|
34
85
|
const langType = sfc.scriptSetup?.lang
|
|
86
|
+
if (!sfc.scriptSetup && shouldInjectRootToastHost) {
|
|
87
|
+
ms.append(`<script ${langType ? `lang="${langType}"` : ''}>
|
|
88
|
+
${getRootToastHostImport(rootToastHostImportPath)}export default {
|
|
89
|
+
components: { UpRootToastHost },
|
|
90
|
+
options: {
|
|
91
|
+
virtualHost: true,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
</script>`)
|
|
95
|
+
return ms
|
|
96
|
+
}
|
|
35
97
|
ms.append(`<script ${langType ? `lang="${langType}"` : ''}>
|
|
36
98
|
export default {
|
|
37
99
|
options: {
|
|
@@ -40,5 +102,13 @@ export async function rebuildUpApp(code, enabledVirtualHost = false) {
|
|
|
40
102
|
}\n</script>`)
|
|
41
103
|
}
|
|
42
104
|
|
|
105
|
+
if (!sfc?.script && !sfc?.scriptSetup && shouldInjectRootToastHost) {
|
|
106
|
+
ms.append(`<script>
|
|
107
|
+
${getRootToastHostImport(rootToastHostImportPath)}export default {
|
|
108
|
+
components: { UpRootToastHost },
|
|
109
|
+
}
|
|
110
|
+
</script>`)
|
|
111
|
+
}
|
|
112
|
+
|
|
43
113
|
return ms
|
|
44
114
|
}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
const DEFAULT_TIMEOUT = 15000
|
|
2
|
+
const DEFAULT_CHUNK_SIZE = 64 * 1024
|
|
3
|
+
|
|
4
|
+
function normalizeMessage(input) {
|
|
5
|
+
const data = input && input.detail ? input.detail.data : input
|
|
6
|
+
if (Array.isArray(data)) {
|
|
7
|
+
return data[data.length - 1] || null
|
|
8
|
+
}
|
|
9
|
+
return data || null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function toError(error, fallback) {
|
|
13
|
+
if (error instanceof Error) return error
|
|
14
|
+
if (error && error.message) return new Error(error.message)
|
|
15
|
+
return new Error(error ? String(error) : fallback)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function createWebViewCanvasBridge(options = {}) {
|
|
19
|
+
const getWebView = typeof options.getWebView === 'function'
|
|
20
|
+
? options.getWebView
|
|
21
|
+
: () => options.webView
|
|
22
|
+
const chunkSize = Math.max(1024, Number(options.chunkSize) || DEFAULT_CHUNK_SIZE)
|
|
23
|
+
const pending = Object.create(null)
|
|
24
|
+
const readyWaiters = []
|
|
25
|
+
let sequence = 0
|
|
26
|
+
let destroyed = false
|
|
27
|
+
let readyInfo = null
|
|
28
|
+
let readyPingTimer = null
|
|
29
|
+
|
|
30
|
+
const rejectPending = (error) => {
|
|
31
|
+
Object.keys(pending).forEach((requestId) => {
|
|
32
|
+
const request = pending[requestId]
|
|
33
|
+
clearTimeout(request.timer)
|
|
34
|
+
delete pending[requestId]
|
|
35
|
+
request.reject(error)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const scheduleReadyPing = () => {
|
|
40
|
+
if (destroyed || readyInfo || readyPingTimer) return
|
|
41
|
+
const ping = () => {
|
|
42
|
+
readyPingTimer = null
|
|
43
|
+
if (destroyed || readyInfo) return
|
|
44
|
+
try {
|
|
45
|
+
const webView = getWebView()
|
|
46
|
+
if (webView && typeof webView.evalJs === 'function') {
|
|
47
|
+
webView.evalJs('window.__upCanvasRuntime && window.__upCanvasRuntime.announceReady()')
|
|
48
|
+
}
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (typeof options.onError === 'function') options.onError(error)
|
|
51
|
+
}
|
|
52
|
+
readyPingTimer = setTimeout(ping, 100)
|
|
53
|
+
}
|
|
54
|
+
ping()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const resolveReady = (message) => {
|
|
58
|
+
const previousSessionId = readyInfo && readyInfo.sessionId
|
|
59
|
+
if (previousSessionId && message.sessionId && previousSessionId !== message.sessionId) {
|
|
60
|
+
rejectPending(new Error('Canvas WebView reloaded'))
|
|
61
|
+
}
|
|
62
|
+
readyInfo = message
|
|
63
|
+
if (readyPingTimer) {
|
|
64
|
+
clearTimeout(readyPingTimer)
|
|
65
|
+
readyPingTimer = null
|
|
66
|
+
}
|
|
67
|
+
readyWaiters.splice(0).forEach((waiter) => {
|
|
68
|
+
clearTimeout(waiter.timer)
|
|
69
|
+
waiter.resolve(message)
|
|
70
|
+
})
|
|
71
|
+
if (typeof options.onReady === 'function') options.onReady(message)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const ready = (timeout = DEFAULT_TIMEOUT) => {
|
|
75
|
+
if (destroyed) return Promise.reject(new Error('Canvas WebView bridge destroyed'))
|
|
76
|
+
if (readyInfo) return Promise.resolve(readyInfo)
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const waiter = {
|
|
79
|
+
resolve,
|
|
80
|
+
reject,
|
|
81
|
+
timer: setTimeout(() => {
|
|
82
|
+
const index = readyWaiters.indexOf(waiter)
|
|
83
|
+
if (index !== -1) readyWaiters.splice(index, 1)
|
|
84
|
+
reject(new Error('Canvas WebView ready timeout'))
|
|
85
|
+
}, timeout)
|
|
86
|
+
}
|
|
87
|
+
readyWaiters.push(waiter)
|
|
88
|
+
scheduleReadyPing()
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const settleRequest = (requestId, error, result) => {
|
|
93
|
+
const request = pending[requestId]
|
|
94
|
+
if (!request) return false
|
|
95
|
+
clearTimeout(request.timer)
|
|
96
|
+
delete pending[requestId]
|
|
97
|
+
if (error) request.reject(error)
|
|
98
|
+
else request.resolve(result)
|
|
99
|
+
return true
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const request = async (type, payload, timeout = DEFAULT_TIMEOUT) => {
|
|
103
|
+
await ready(timeout)
|
|
104
|
+
if (destroyed) throw new Error('Canvas WebView bridge destroyed')
|
|
105
|
+
|
|
106
|
+
const webView = getWebView()
|
|
107
|
+
if (!webView || typeof webView.evalJs !== 'function') {
|
|
108
|
+
throw new Error('Canvas WebView is unavailable')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const requestId = ++sequence
|
|
112
|
+
const serialized = JSON.stringify({ requestId, type, payload: payload || {} })
|
|
113
|
+
const total = Math.max(1, Math.ceil(serialized.length / chunkSize))
|
|
114
|
+
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
pending[requestId] = {
|
|
117
|
+
resolve,
|
|
118
|
+
reject,
|
|
119
|
+
timer: setTimeout(() => {
|
|
120
|
+
settleRequest(requestId, new Error(`Canvas ${type} request timeout`))
|
|
121
|
+
}, timeout)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const asyncSends = []
|
|
126
|
+
for (let index = 0; index < total; index += 1) {
|
|
127
|
+
const chunk = serialized.slice(index * chunkSize, (index + 1) * chunkSize)
|
|
128
|
+
const result = webView.evalJs(
|
|
129
|
+
`window.__upCanvasRuntime.receiveChunk(${JSON.stringify(requestId)}, ${index}, ${total}, ${JSON.stringify(chunk)})`
|
|
130
|
+
)
|
|
131
|
+
if (result && typeof result.then === 'function') asyncSends.push(result)
|
|
132
|
+
}
|
|
133
|
+
if (asyncSends.length) {
|
|
134
|
+
Promise.all(asyncSends).catch((error) => {
|
|
135
|
+
settleRequest(requestId, toError(error, 'Canvas request dispatch failed'))
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
} catch (error) {
|
|
139
|
+
settleRequest(requestId, toError(error, 'Canvas request dispatch failed'))
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const handleMessage = (input) => {
|
|
145
|
+
const message = normalizeMessage(input)
|
|
146
|
+
if (!message || message.channel !== 'u-canvas') return false
|
|
147
|
+
|
|
148
|
+
if (message.action === 'canvasReady') {
|
|
149
|
+
resolveReady(message)
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
if (message.action === 'canvasTouch') {
|
|
153
|
+
if (typeof options.onTouch === 'function') options.onTouch(message)
|
|
154
|
+
return true
|
|
155
|
+
}
|
|
156
|
+
if (message.action === 'canvasResponse') {
|
|
157
|
+
return settleRequest(message.requestId, null, message.result)
|
|
158
|
+
}
|
|
159
|
+
if (message.action === 'canvasError') {
|
|
160
|
+
const error = new Error(message.message || 'Canvas WebView request failed')
|
|
161
|
+
if (!settleRequest(message.requestId, error) && typeof options.onError === 'function') {
|
|
162
|
+
options.onError(error)
|
|
163
|
+
}
|
|
164
|
+
return true
|
|
165
|
+
}
|
|
166
|
+
return false
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const destroy = () => {
|
|
170
|
+
if (destroyed) return
|
|
171
|
+
destroyed = true
|
|
172
|
+
if (readyPingTimer) clearTimeout(readyPingTimer)
|
|
173
|
+
readyPingTimer = null
|
|
174
|
+
const error = new Error('Canvas WebView bridge destroyed')
|
|
175
|
+
readyWaiters.splice(0).forEach((waiter) => {
|
|
176
|
+
clearTimeout(waiter.timer)
|
|
177
|
+
waiter.reject(error)
|
|
178
|
+
})
|
|
179
|
+
rejectPending(error)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
ready,
|
|
184
|
+
request,
|
|
185
|
+
handleMessage,
|
|
186
|
+
destroy
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function normalizeImageDataArgs(args) {
|
|
191
|
+
if (args.length === 1 && args[0] && typeof args[0] === 'object') return args[0]
|
|
192
|
+
return { x: args[0], y: args[1], width: args[2], height: args[3] }
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function normalizePutImageDataArgs(args) {
|
|
196
|
+
if (args.length === 1 && args[0] && typeof args[0] === 'object') return args[0]
|
|
197
|
+
return { data: args[0], x: args[1], y: args[2], width: args[3], height: args[4] }
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function cloneOptions(options) {
|
|
201
|
+
const result = {}
|
|
202
|
+
Object.keys(options || {}).forEach((key) => {
|
|
203
|
+
if (typeof options[key] !== 'function') result[key] = options[key]
|
|
204
|
+
})
|
|
205
|
+
return result
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function withCallbacks(promise, options) {
|
|
209
|
+
const success = options && options.success
|
|
210
|
+
const fail = options && options.fail
|
|
211
|
+
const complete = options && options.complete
|
|
212
|
+
return promise.then((result) => {
|
|
213
|
+
if (typeof success === 'function') success(result)
|
|
214
|
+
if (typeof complete === 'function') complete(result)
|
|
215
|
+
return result
|
|
216
|
+
}, (error) => {
|
|
217
|
+
if (typeof fail === 'function') fail(error)
|
|
218
|
+
if (typeof complete === 'function') complete(error)
|
|
219
|
+
throw error
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function createWebViewCanvasContext(options = {}) {
|
|
224
|
+
const bridge = options.bridge
|
|
225
|
+
if (!bridge || typeof bridge.request !== 'function') {
|
|
226
|
+
throw new Error('Canvas WebView bridge is required')
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const resolveImage = typeof options.resolveImage === 'function'
|
|
230
|
+
? options.resolveImage
|
|
231
|
+
: source => Promise.resolve(source)
|
|
232
|
+
const measureTextFallback = typeof options.measureText === 'function'
|
|
233
|
+
? options.measureText
|
|
234
|
+
: (text, state) => {
|
|
235
|
+
const matched = String(state.font || '').match(/(\d+(?:\.\d+)?)px/)
|
|
236
|
+
const fontSize = matched ? Number(matched[1]) : 10
|
|
237
|
+
return { width: String(text).length * fontSize * 0.6 }
|
|
238
|
+
}
|
|
239
|
+
const state = {
|
|
240
|
+
fillStyle: '#000000',
|
|
241
|
+
strokeStyle: '#000000',
|
|
242
|
+
lineWidth: 1,
|
|
243
|
+
lineCap: 'butt',
|
|
244
|
+
lineJoin: 'miter',
|
|
245
|
+
miterLimit: 10,
|
|
246
|
+
globalAlpha: 1,
|
|
247
|
+
globalCompositeOperation: 'source-over',
|
|
248
|
+
font: '10px sans-serif',
|
|
249
|
+
textAlign: 'start',
|
|
250
|
+
textBaseline: 'alphabetic',
|
|
251
|
+
shadowOffsetX: 0,
|
|
252
|
+
shadowOffsetY: 0,
|
|
253
|
+
shadowBlur: 0,
|
|
254
|
+
shadowColor: 'rgba(0,0,0,0)',
|
|
255
|
+
lineDashOffset: 0,
|
|
256
|
+
lineDash: []
|
|
257
|
+
}
|
|
258
|
+
const context = {}
|
|
259
|
+
let commands = []
|
|
260
|
+
let resources = Object.create(null)
|
|
261
|
+
let resourceSequence = 0
|
|
262
|
+
let drawTail = Promise.resolve()
|
|
263
|
+
let lastDraw = drawTail
|
|
264
|
+
|
|
265
|
+
const nextResourceId = type => `${type}-${++resourceSequence}`
|
|
266
|
+
const rememberResource = (resource) => {
|
|
267
|
+
resources[resource.id] = resource
|
|
268
|
+
return { __upCanvasRef: resource.id }
|
|
269
|
+
}
|
|
270
|
+
const serializeValue = (value) => {
|
|
271
|
+
if (value && value.__upCanvasResource) return rememberResource(value)
|
|
272
|
+
if (Array.isArray(value)) return value.map(serializeValue)
|
|
273
|
+
return value
|
|
274
|
+
}
|
|
275
|
+
const enqueueCall = (method, args) => {
|
|
276
|
+
commands.push({
|
|
277
|
+
type: 'call',
|
|
278
|
+
method,
|
|
279
|
+
args: (args || []).map(serializeValue)
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
const enqueueSet = (property, value) => {
|
|
283
|
+
commands.push({
|
|
284
|
+
type: 'set',
|
|
285
|
+
property,
|
|
286
|
+
value: serializeValue(value)
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
const property = name => ({
|
|
290
|
+
enumerable: true,
|
|
291
|
+
configurable: false,
|
|
292
|
+
get() {
|
|
293
|
+
return state[name]
|
|
294
|
+
},
|
|
295
|
+
set(value) {
|
|
296
|
+
state[name] = value
|
|
297
|
+
enqueueSet(name, value)
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
Object.defineProperties(context, {
|
|
302
|
+
fillStyle: property('fillStyle'),
|
|
303
|
+
strokeStyle: property('strokeStyle'),
|
|
304
|
+
lineWidth: property('lineWidth'),
|
|
305
|
+
lineCap: property('lineCap'),
|
|
306
|
+
lineJoin: property('lineJoin'),
|
|
307
|
+
miterLimit: property('miterLimit'),
|
|
308
|
+
globalAlpha: property('globalAlpha'),
|
|
309
|
+
globalCompositeOperation: property('globalCompositeOperation'),
|
|
310
|
+
font: property('font'),
|
|
311
|
+
textAlign: property('textAlign'),
|
|
312
|
+
textBaseline: property('textBaseline'),
|
|
313
|
+
shadowOffsetX: property('shadowOffsetX'),
|
|
314
|
+
shadowOffsetY: property('shadowOffsetY'),
|
|
315
|
+
shadowBlur: property('shadowBlur'),
|
|
316
|
+
shadowColor: property('shadowColor'),
|
|
317
|
+
lineDashOffset: property('lineDashOffset')
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
const methodOperations = [
|
|
321
|
+
'rect', 'clearRect', 'fillRect', 'strokeRect', 'fill', 'stroke',
|
|
322
|
+
'beginPath', 'closePath', 'moveTo', 'lineTo', 'arc', 'arcTo',
|
|
323
|
+
'bezierCurveTo', 'quadraticCurveTo', 'ellipse', 'clip', 'save',
|
|
324
|
+
'restore', 'translate', 'rotate', 'scale', 'setTransform',
|
|
325
|
+
'transform', 'resetTransform', 'fillText', 'strokeText'
|
|
326
|
+
]
|
|
327
|
+
methodOperations.forEach((method) => {
|
|
328
|
+
context[method] = (...args) => enqueueCall(method, args)
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
const createGradient = (kind, args) => {
|
|
332
|
+
const resource = {
|
|
333
|
+
__upCanvasResource: true,
|
|
334
|
+
type: 'gradient',
|
|
335
|
+
id: nextResourceId('gradient'),
|
|
336
|
+
kind,
|
|
337
|
+
args,
|
|
338
|
+
stops: [],
|
|
339
|
+
addColorStop(offset, color) {
|
|
340
|
+
this.stops.push([Number(offset), String(color)])
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return resource
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const imageSource = (source) => {
|
|
347
|
+
if (typeof source === 'string') return source
|
|
348
|
+
if (source && typeof source.src === 'string') return source.src
|
|
349
|
+
throw new Error('Canvas image source must be a string')
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const createImageResource = (source) => ({
|
|
353
|
+
__upCanvasResource: true,
|
|
354
|
+
type: 'image',
|
|
355
|
+
id: nextResourceId('image'),
|
|
356
|
+
source: Promise.resolve().then(() => resolveImage(imageSource(source)))
|
|
357
|
+
})
|
|
358
|
+
|
|
359
|
+
const snapshotResources = (resourceMap) => Object.keys(resourceMap).map((id) => {
|
|
360
|
+
const resource = resourceMap[id]
|
|
361
|
+
if (resource.type === 'gradient') {
|
|
362
|
+
return Promise.resolve({
|
|
363
|
+
type: 'gradient',
|
|
364
|
+
id: resource.id,
|
|
365
|
+
kind: resource.kind,
|
|
366
|
+
args: resource.args.slice(),
|
|
367
|
+
stops: resource.stops.map(stop => stop.slice())
|
|
368
|
+
})
|
|
369
|
+
}
|
|
370
|
+
if (resource.type === 'image') {
|
|
371
|
+
return resource.source.then(src => ({ type: 'image', id: resource.id, src }))
|
|
372
|
+
}
|
|
373
|
+
if (resource.type === 'pattern') {
|
|
374
|
+
return resource.source.then(source => ({
|
|
375
|
+
type: 'pattern',
|
|
376
|
+
id: resource.id,
|
|
377
|
+
source,
|
|
378
|
+
repetition: resource.repetition
|
|
379
|
+
}))
|
|
380
|
+
}
|
|
381
|
+
return Promise.reject(new Error(`Unsupported Canvas resource: ${resource.type}`))
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
context.createLinearGradient = (...args) => createGradient('linear', args)
|
|
385
|
+
context.createRadialGradient = (...args) => createGradient('radial', args)
|
|
386
|
+
context.createConicGradient = (...args) => createGradient('conic', args)
|
|
387
|
+
context.createPattern = (source, repetition = 'repeat') => ({
|
|
388
|
+
__upCanvasResource: true,
|
|
389
|
+
type: 'pattern',
|
|
390
|
+
id: nextResourceId('pattern'),
|
|
391
|
+
source: Promise.resolve().then(() => resolveImage(imageSource(source))),
|
|
392
|
+
repetition
|
|
393
|
+
})
|
|
394
|
+
context.drawImage = (source, ...args) => {
|
|
395
|
+
const resource = source && source.__upCanvasResource
|
|
396
|
+
? source
|
|
397
|
+
: createImageResource(source)
|
|
398
|
+
enqueueCall('drawImage', [resource, ...args])
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
context.setFillStyle = value => { context.fillStyle = value }
|
|
402
|
+
context.setStrokeStyle = value => { context.strokeStyle = value }
|
|
403
|
+
context.setLineWidth = value => { context.lineWidth = value }
|
|
404
|
+
context.setLineCap = value => { context.lineCap = value }
|
|
405
|
+
context.setLineJoin = value => { context.lineJoin = value }
|
|
406
|
+
context.setTextAlign = value => { context.textAlign = value }
|
|
407
|
+
context.setTextBaseline = value => { context.textBaseline = value }
|
|
408
|
+
context.setGlobalAlpha = value => { context.globalAlpha = value }
|
|
409
|
+
context.setMiterLimit = value => { context.miterLimit = value }
|
|
410
|
+
context.setGlobalCompositeOperation = value => { context.globalCompositeOperation = value }
|
|
411
|
+
context.setFont = value => { context.font = value }
|
|
412
|
+
context.setFontSize = value => {
|
|
413
|
+
const size = Number(value) || 10
|
|
414
|
+
context.font = /\d+(?:\.\d+)?px/.test(state.font)
|
|
415
|
+
? state.font.replace(/\d+(?:\.\d+)?px/, `${size}px`)
|
|
416
|
+
: `${size}px sans-serif`
|
|
417
|
+
}
|
|
418
|
+
context.setShadow = (offsetX, offsetY, blur, color) => {
|
|
419
|
+
context.shadowOffsetX = offsetX
|
|
420
|
+
context.shadowOffsetY = offsetY
|
|
421
|
+
context.shadowBlur = blur
|
|
422
|
+
context.shadowColor = color
|
|
423
|
+
}
|
|
424
|
+
context.setLineDash = (segments) => {
|
|
425
|
+
state.lineDash = Array.isArray(segments) ? segments.slice() : []
|
|
426
|
+
enqueueCall('setLineDash', [state.lineDash])
|
|
427
|
+
}
|
|
428
|
+
context.getLineDash = () => state.lineDash.slice()
|
|
429
|
+
|
|
430
|
+
context.measureText = text => measureTextFallback(String(text), state)
|
|
431
|
+
context.measureTextAsync = text => bridge.request('measureText', {
|
|
432
|
+
text: String(text),
|
|
433
|
+
font: state.font
|
|
434
|
+
})
|
|
435
|
+
|
|
436
|
+
context.draw = (reserve = false, callback) => {
|
|
437
|
+
const batchCommands = commands
|
|
438
|
+
const batchResources = resources
|
|
439
|
+
commands = []
|
|
440
|
+
resources = Object.create(null)
|
|
441
|
+
const execute = async () => {
|
|
442
|
+
const definitions = await Promise.all(snapshotResources(batchResources))
|
|
443
|
+
return bridge.request('draw', {
|
|
444
|
+
reserve: !!reserve,
|
|
445
|
+
commands: batchCommands,
|
|
446
|
+
resources: definitions
|
|
447
|
+
})
|
|
448
|
+
}
|
|
449
|
+
const operation = drawTail.then(execute, execute)
|
|
450
|
+
drawTail = operation.catch(() => {})
|
|
451
|
+
lastDraw = operation
|
|
452
|
+
if (typeof callback === 'function') operation.then(result => callback(result))
|
|
453
|
+
return operation
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
context.toTempFilePath = (options = {}) => withCallbacks(
|
|
457
|
+
lastDraw.then(() => bridge.request('export', cloneOptions(options))),
|
|
458
|
+
options
|
|
459
|
+
)
|
|
460
|
+
context.getImageData = (...args) => {
|
|
461
|
+
const options = normalizeImageDataArgs(args)
|
|
462
|
+
return withCallbacks(
|
|
463
|
+
lastDraw.then(() => bridge.request('getImageData', cloneOptions(options))),
|
|
464
|
+
options
|
|
465
|
+
)
|
|
466
|
+
}
|
|
467
|
+
context.putImageData = (...args) => {
|
|
468
|
+
const options = normalizePutImageDataArgs(args)
|
|
469
|
+
const payload = cloneOptions(options)
|
|
470
|
+
if (payload.data && payload.data.data) {
|
|
471
|
+
payload.data = {
|
|
472
|
+
width: payload.data.width,
|
|
473
|
+
height: payload.data.height,
|
|
474
|
+
data: Array.from(payload.data.data)
|
|
475
|
+
}
|
|
476
|
+
} else if (payload.data && !Array.isArray(payload.data)) {
|
|
477
|
+
payload.data = Array.from(payload.data)
|
|
478
|
+
}
|
|
479
|
+
return withCallbacks(
|
|
480
|
+
lastDraw.then(() => bridge.request('putImageData', payload)),
|
|
481
|
+
options
|
|
482
|
+
)
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
return context
|
|
486
|
+
}
|
|
@@ -218,9 +218,7 @@ const GBridge = {
|
|
|
218
218
|
},
|
|
219
219
|
|
|
220
220
|
perloadImage([url, id], callback) {
|
|
221
|
-
console.log('********************asda**********')
|
|
222
221
|
GCanvasModule.preLoadImage([url, id], function (image) {
|
|
223
|
-
console.log('********************asda2**********')
|
|
224
222
|
image.url = url;
|
|
225
223
|
image.id = id;
|
|
226
224
|
callback(image);
|
|
@@ -10,7 +10,7 @@ export let Image = GImage;
|
|
|
10
10
|
|
|
11
11
|
export let WeexBridge = GBridgeWeex;
|
|
12
12
|
|
|
13
|
-
export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands } = {}) {
|
|
13
|
+
export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommands, clearColor = 'white' } = {}) {
|
|
14
14
|
|
|
15
15
|
const GBridge = GImage.GBridge = GCanvas.GBridge = GWebGLRenderingContext.GBridge = GContext2D.GBridge = bridge;
|
|
16
16
|
|
|
@@ -20,7 +20,7 @@ export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommand
|
|
|
20
20
|
false, // supportScroll
|
|
21
21
|
false, // newCanvasMode
|
|
22
22
|
1, // compatible
|
|
23
|
-
|
|
23
|
+
clearColor,// clearColor
|
|
24
24
|
false // sameLevel: newCanvasMode = true && true => GCanvasView and Webview is same level
|
|
25
25
|
]);
|
|
26
26
|
|
|
@@ -36,4 +36,4 @@ export function enable(el, { bridge, debug, disableAutoSwap, disableComboCommand
|
|
|
36
36
|
canvas.height = el.style.height;
|
|
37
37
|
|
|
38
38
|
return canvas;
|
|
39
|
-
};
|
|
39
|
+
};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "uview-plus",
|
|
3
3
|
"name": "uview-plus",
|
|
4
4
|
"displayName": "零云®uview-plus3.0重磅发布,全面的Vue3鸿蒙跨端移动组件库,组件丰富维护更新稳定。",
|
|
5
|
-
"version": "3.8.
|
|
5
|
+
"version": "3.8.108",
|
|
6
6
|
"description": "零云®uview-plus已兼容vue3支持多语言,120+全面的组件和便捷的工具会让您信手拈来。近期新增拖动排序、条码、图片裁剪、下拉刷新、虚拟列表、签名、Markdown等。",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"uview",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"echarts",
|
|
12
12
|
"ui",
|
|
13
13
|
"可视化"
|
|
14
|
-
|
|
14
|
+
],
|
|
15
15
|
"main": "index.js",
|
|
16
16
|
"repository": "https://github.com/ijry/uview-plus",
|
|
17
17
|
"engines": {
|
|
@@ -20,6 +20,11 @@ declare interface SwipeActionItemProps {
|
|
|
20
20
|
* @default true
|
|
21
21
|
*/
|
|
22
22
|
autoClose?: boolean
|
|
23
|
+
/**
|
|
24
|
+
* 是否正在横向滑动,可用于 v-model:scrolling 暂停外部滚动
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
scrolling?: boolean
|
|
23
28
|
/**
|
|
24
29
|
* 滑动距离阈值,只有大于此值,才被认为是要打开菜单
|
|
25
30
|
* @default 20
|
|
@@ -44,6 +49,14 @@ declare interface SwipeActionItemProps {
|
|
|
44
49
|
* @param index 第几个按钮被点击
|
|
45
50
|
*/
|
|
46
51
|
onClick?: (name: any, index: number) => any
|
|
52
|
+
/**
|
|
53
|
+
* scrolling 双向绑定更新
|
|
54
|
+
*/
|
|
55
|
+
['onUpdate:scrolling']?: (value: boolean) => any
|
|
56
|
+
/**
|
|
57
|
+
* 横向滑动状态变化时触发
|
|
58
|
+
*/
|
|
59
|
+
onScrolling?: (value: boolean) => any
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
|
package/types/comps/tabs.d.ts
CHANGED
|
@@ -69,8 +69,9 @@ declare interface TabsProps {
|
|
|
69
69
|
* 点击标签时触发
|
|
70
70
|
* @param item 传入的其他值
|
|
71
71
|
* @param index 标签索引值
|
|
72
|
+
* @param event 原始点击事件,H5 下为 DOM Event
|
|
72
73
|
*/
|
|
73
|
-
onClick?: (item: any, index: number) => any
|
|
74
|
+
onClick?: (item: any, index: number, event: any) => any
|
|
74
75
|
/**
|
|
75
76
|
* 标签索引改变时触发(`disalbed`时不会触发)
|
|
76
77
|
* @param item 传入的其他值
|