@tarojs/plugin-platform-harmony-cpp 4.1.0 → 4.1.1-alpha.0
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/dist/index.js +1237 -0
- package/dist/runtime/apis/apis.ts +20 -0
- package/dist/runtime/apis/base/crypto.ts +4 -0
- package/dist/runtime/apis/base/debug.ts +5 -0
- package/dist/runtime/apis/base/index.ts +13 -0
- package/dist/runtime/apis/base/performance.ts +8 -0
- package/dist/runtime/apis/base/system.ts +181 -0
- package/dist/runtime/apis/base/update.ts +5 -0
- package/dist/runtime/apis/base/weapp/app-event.ts +75 -0
- package/dist/runtime/apis/base/weapp/life-cycle.ts +21 -0
- package/dist/runtime/apis/canvas/index.ts +27 -0
- package/dist/runtime/apis/data-analysis/index.ts +6 -0
- package/dist/runtime/apis/device/accelerometer.ts +79 -0
- package/dist/runtime/apis/device/accessibility.ts +4 -0
- package/dist/runtime/apis/device/battery.ts +24 -0
- package/dist/runtime/apis/device/bluetooth-ble.ts +19 -0
- package/dist/runtime/apis/device/bluetooth-peripheral.ts +6 -0
- package/dist/runtime/apis/device/bluetooth.ts +16 -0
- package/dist/runtime/apis/device/calendar.ts +5 -0
- package/dist/runtime/apis/device/clipboard.ts +85 -0
- package/dist/runtime/apis/device/compass.ts +21 -0
- package/dist/runtime/apis/device/contact.ts +5 -0
- package/dist/runtime/apis/device/crypto.ts +4 -0
- package/dist/runtime/apis/device/gyroscope.ts +77 -0
- package/dist/runtime/apis/device/iBeacon.ts +10 -0
- package/dist/runtime/apis/device/index.ts +24 -0
- package/dist/runtime/apis/device/keyboard.ts +63 -0
- package/dist/runtime/apis/device/memory.ts +11 -0
- package/dist/runtime/apis/device/motion.ts +6 -0
- package/dist/runtime/apis/device/network.ts +123 -0
- package/dist/runtime/apis/device/nfc.ts +10 -0
- package/dist/runtime/apis/device/phone.ts +44 -0
- package/dist/runtime/apis/device/scan.ts +4 -0
- package/dist/runtime/apis/device/screen.ts +80 -0
- package/dist/runtime/apis/device/sms.ts +4 -0
- package/dist/runtime/apis/device/vibrate.ts +32 -0
- package/dist/runtime/apis/device/wifi.ts +15 -0
- package/dist/runtime/apis/ext/index.ts +5 -0
- package/dist/runtime/apis/files/index.ts +136 -0
- package/dist/runtime/apis/files/manager.ts +942 -0
- package/dist/runtime/apis/framework/index.ts +48 -0
- package/dist/runtime/apis/harmony/task-pool.ts +39 -0
- package/dist/runtime/apis/index.ts +61 -0
- package/dist/runtime/apis/location/index.ts +133 -0
- package/dist/runtime/apis/media/EditorContext.ts +32 -0
- package/dist/runtime/apis/media/audio/index.ts +36 -0
- package/dist/runtime/apis/media/background-audio/index.ts +16 -0
- package/dist/runtime/apis/media/camera.ts +16 -0
- package/dist/runtime/apis/media/common.ts +58 -0
- package/dist/runtime/apis/media/image/index.ts +291 -0
- package/dist/runtime/apis/media/index.ts +13 -0
- package/dist/runtime/apis/media/live.ts +5 -0
- package/dist/runtime/apis/media/map.ts +4 -0
- package/dist/runtime/apis/media/media-recorder.ts +4 -0
- package/dist/runtime/apis/media/recorder.ts +6 -0
- package/dist/runtime/apis/media/video/VideoContext.ts +67 -0
- package/dist/runtime/apis/media/video/index.ts +45 -0
- package/dist/runtime/apis/media/video-decoder.ts +4 -0
- package/dist/runtime/apis/media/video-processing.ts +4 -0
- package/dist/runtime/apis/media/voip.ts +19 -0
- package/dist/runtime/apis/navigate/index.ts +8 -0
- package/dist/runtime/apis/network/downloadFile.ts +85 -0
- package/dist/runtime/apis/network/index.ts +7 -0
- package/dist/runtime/apis/network/mdns.ts +13 -0
- package/dist/runtime/apis/network/request.ts +140 -0
- package/dist/runtime/apis/network/tcp.ts +4 -0
- package/dist/runtime/apis/network/udp.ts +4 -0
- package/dist/runtime/apis/network/uploadFile.ts +105 -0
- package/dist/runtime/apis/network/webSocket.ts +126 -0
- package/dist/runtime/apis/open-api/account.ts +4 -0
- package/dist/runtime/apis/open-api/address.ts +4 -0
- package/dist/runtime/apis/open-api/authorize.ts +5 -0
- package/dist/runtime/apis/open-api/card.ts +5 -0
- package/dist/runtime/apis/open-api/channels-live.ts +11 -0
- package/dist/runtime/apis/open-api/customer-service.ts +4 -0
- package/dist/runtime/apis/open-api/device-voip.ts +5 -0
- package/dist/runtime/apis/open-api/facial.ts +7 -0
- package/dist/runtime/apis/open-api/favorites.ts +5 -0
- package/dist/runtime/apis/open-api/group.ts +4 -0
- package/dist/runtime/apis/open-api/index.ts +21 -0
- package/dist/runtime/apis/open-api/invoice.ts +5 -0
- package/dist/runtime/apis/open-api/license-plate.ts +4 -0
- package/dist/runtime/apis/open-api/login.ts +6 -0
- package/dist/runtime/apis/open-api/my-miniprogram.ts +4 -0
- package/dist/runtime/apis/open-api/privacy.ts +7 -0
- package/dist/runtime/apis/open-api/red-package.ts +4 -0
- package/dist/runtime/apis/open-api/settings.ts +5 -0
- package/dist/runtime/apis/open-api/soter.ts +6 -0
- package/dist/runtime/apis/open-api/subscribe-message.ts +6 -0
- package/dist/runtime/apis/open-api/user-info.ts +70 -0
- package/dist/runtime/apis/open-api/werun.ts +5 -0
- package/dist/runtime/apis/payment/index.ts +6 -0
- package/dist/runtime/apis/route/index.ts +88 -0
- package/dist/runtime/apis/share/index.ts +33 -0
- package/dist/runtime/apis/storage/background-fetch.ts +7 -0
- package/dist/runtime/apis/storage/cache-manager.ts +4 -0
- package/dist/runtime/apis/storage/index.ts +203 -0
- package/dist/runtime/apis/ui/animation/animation.ts +264 -0
- package/dist/runtime/apis/ui/animation/index.ts +7 -0
- package/dist/runtime/apis/ui/background.ts +20 -0
- package/dist/runtime/apis/ui/custom-component.ts +1 -0
- package/dist/runtime/apis/ui/fonts.ts +4 -0
- package/dist/runtime/apis/ui/index.ts +12 -0
- package/dist/runtime/apis/ui/interaction/index.ts +198 -0
- package/dist/runtime/apis/ui/menu.ts +4 -0
- package/dist/runtime/apis/ui/navigation-bar/index.ts +72 -0
- package/dist/runtime/apis/ui/pull-down-refresh.ts +47 -0
- package/dist/runtime/apis/ui/scroll/index.ts +82 -0
- package/dist/runtime/apis/ui/sticky.ts +4 -0
- package/dist/runtime/apis/ui/tab-bar.ts +144 -0
- package/dist/runtime/apis/ui/window.ts +20 -0
- package/dist/runtime/apis/utils/constant.ts +1 -0
- package/dist/runtime/apis/utils/handler.ts +117 -0
- package/dist/runtime/apis/utils/index.ts +105 -0
- package/dist/runtime/apis/utils/permissions.ts +6 -0
- package/dist/runtime/apis/utils/types.ts +12 -0
- package/dist/runtime/apis/utils/unit.ts +104 -0
- package/dist/runtime/apis/utils/validate.ts +87 -0
- package/dist/runtime/apis/worker/index.ts +4 -0
- package/dist/runtime/apis/wxml/index.ts +17 -0
- package/dist/runtime/apis/wxml/intersectionObserver.ts +100 -0
- package/dist/runtime/apis/wxml/nodesRef.ts +58 -0
- package/dist/runtime/apis/wxml/selectorQuery.ts +221 -0
- package/dist/runtime/apischunk/index.d.ts +802 -0
- package/dist/runtime/apischunk/index.js +5054 -0
- package/dist/runtime/components/deprecated.ets +43 -0
- package/dist/runtime/components/index.ets +49 -0
- package/dist/runtime/components/innerHtml.ets +16 -0
- package/dist/runtime/components/navigationBar.ets +65 -0
- package/dist/runtime/components/pageMeta.ets +94 -0
- package/dist/runtime/components/richText.ets +24 -0
- package/dist/runtime/components/slider.ets +119 -0
- package/dist/runtime/components/style.ets +286 -0
- package/dist/runtime/components/switch.ets +73 -0
- package/dist/runtime/components/tag.ts +58 -0
- package/dist/runtime/components/utils/AttributeManager.ets +252 -0
- package/dist/runtime/components/utils/DynamicCenter.ts +41 -0
- package/dist/runtime/components/utils/constant/event.ets +25 -0
- package/dist/runtime/components/utils/constant/style.ets +91 -0
- package/dist/runtime/components/utils/events.ts +26 -0
- package/dist/runtime/components/utils/flexManager.ets +49 -0
- package/dist/runtime/components/utils/helper.ets +51 -0
- package/dist/runtime/components/utils/htmlParser/HarmonyHTMLParser.ts +100 -0
- package/dist/runtime/components/utils/htmlParser/index.ts +58 -0
- package/dist/runtime/components/utils/index.ts +77 -0
- package/dist/runtime/components/utils/styles.ets +41 -0
- package/dist/runtime/components/video.ets +119 -0
- package/dist/runtime/components/webView.ets +55 -0
- package/dist/runtime/components/xComponent.ets +89 -0
- package/dist/runtime/framework/app.ts +248 -0
- package/dist/runtime/framework/connect.ts +24 -0
- package/dist/runtime/framework/constant.ts +3 -0
- package/dist/runtime/framework/hooks.ts +99 -0
- package/dist/runtime/framework/index.ts +15 -0
- package/dist/runtime/framework/native-page.ts +511 -0
- package/dist/runtime/framework/page.ts +256 -0
- package/dist/runtime/framework/utils/index.ts +17 -0
- package/dist/runtime/framework/utils/is.ts +26 -0
- package/dist/runtime/framework-reconciler/componentTree.ts +81 -0
- package/dist/runtime/framework-reconciler/constant.ts +86 -0
- package/dist/runtime/framework-reconciler/domInput.ts +90 -0
- package/dist/runtime/framework-reconciler/event.ts +108 -0
- package/dist/runtime/framework-reconciler/index.ts +99 -0
- package/dist/runtime/framework-reconciler/inputValueTracking.ts +106 -0
- package/dist/runtime/framework-reconciler/props.ts +132 -0
- package/dist/runtime/framework-reconciler/reconciler.ts +202 -0
- package/dist/runtime/framework-reconciler/render.ts +139 -0
- package/dist/runtime/framework-reconciler/workTags.ts +53 -0
- package/dist/runtime/runtime-cpp/bom/URL.ts +2 -0
- package/dist/runtime/runtime-cpp/bom/document.ts +45 -0
- package/dist/runtime/runtime-cpp/bom/history.ts +1 -0
- package/dist/runtime/runtime-cpp/bom/location.ts +1 -0
- package/dist/runtime/runtime-cpp/bom/navigator.ts +1 -0
- package/dist/runtime/runtime-cpp/bom/raf.ts +1 -0
- package/dist/runtime/runtime-cpp/bom/window.ts +57 -0
- package/dist/runtime/runtime-cpp/constant.ts +29 -0
- package/dist/runtime/runtime-cpp/current.ts +48 -0
- package/dist/runtime/runtime-cpp/dom/class-list.ts +41 -0
- package/dist/runtime/runtime-cpp/dom/comment.ts +9 -0
- package/dist/runtime/runtime-cpp/dom/dataSource.ts +87 -0
- package/dist/runtime/runtime-cpp/dom/document.ts +113 -0
- package/dist/runtime/runtime-cpp/dom/element/canvas.ts +285 -0
- package/dist/runtime/runtime-cpp/dom/element/element.ts +262 -0
- package/dist/runtime/runtime-cpp/dom/element/form.ts +371 -0
- package/dist/runtime/runtime-cpp/dom/element/index.ts +129 -0
- package/dist/runtime/runtime-cpp/dom/element/movable.ts +250 -0
- package/dist/runtime/runtime-cpp/dom/element/normal.ts +123 -0
- package/dist/runtime/runtime-cpp/dom/element/scroll_view.ts +32 -0
- package/dist/runtime/runtime-cpp/dom/element/text.ts +9 -0
- package/dist/runtime/runtime-cpp/dom/element/video.ts +66 -0
- package/dist/runtime/runtime-cpp/dom/element/web_view.ts +72 -0
- package/dist/runtime/runtime-cpp/dom/event-source.ts +1 -0
- package/dist/runtime/runtime-cpp/dom/event.ts +187 -0
- package/dist/runtime/runtime-cpp/dom/eventTarget.ts +81 -0
- package/dist/runtime/runtime-cpp/dom/node.ts +307 -0
- package/dist/runtime/runtime-cpp/dom/style.ts +44 -0
- package/dist/runtime/runtime-cpp/dom/stylesheet/index.ts +379 -0
- package/dist/runtime/runtime-cpp/dom/stylesheet/type.ts +212 -0
- package/dist/runtime/runtime-cpp/dom/stylesheet/util.ts +186 -0
- package/dist/runtime/runtime-cpp/emitter/emitter.ts +29 -0
- package/dist/runtime/runtime-cpp/env.ts +1 -0
- package/dist/runtime/runtime-cpp/harmony-library.ts +1 -0
- package/dist/runtime/runtime-cpp/index.ts +79 -0
- package/dist/runtime/runtime-cpp/interface/event.ts +10 -0
- package/dist/runtime/runtime-cpp/interface/index.ts +7 -0
- package/dist/runtime/runtime-cpp/next-tick.ts +14 -0
- package/dist/runtime/runtime-cpp/system.ts +213 -0
- package/dist/runtime/runtime-cpp/utils/index.ts +63 -0
- package/dist/runtime/runtime-cpp/utils/info.ts +123 -0
- package/dist/runtime/runtime-cpp/utils/page.ts +12 -0
- package/dist/runtime/runtime-cpp/utils/router.ts +1 -0
- package/dist/runtime/runtime-harmony/apis/helper.ets +33 -0
- package/dist/runtime/runtime-harmony/apis/network/common.ets +41 -0
- package/dist/runtime/runtime-harmony/apis/network/downloadFile.ets +327 -0
- package/dist/runtime/runtime-harmony/apis/network/index.ets +58 -0
- package/dist/runtime/runtime-harmony/apis/network/request.ets +206 -0
- package/dist/runtime/runtime-harmony/apis/network/uploadFile.ets +190 -0
- package/dist/runtime/runtime-harmony/apis/route.ets +110 -0
- package/dist/runtime/runtime-harmony/apis/taskpool.ets +149 -0
- package/dist/runtime/runtime-harmony/index.ets +41 -0
- package/dist/runtime/runtime-harmony/utils.ts +53 -0
- package/package.json +24 -23
- package/LICENSE +0 -174
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { IEtsMethodsOptions } from '../../index'
|
|
2
|
+
import type { TaroAny } from '../../../../../../runtime'
|
|
3
|
+
|
|
4
|
+
import { rcp } from '@kit.RemoteCommunicationKit';
|
|
5
|
+
import { url, util } from '@kit.ArkTS';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
IGeneralCallbackResult,
|
|
9
|
+
IHeaderCallBackArgs,
|
|
10
|
+
convertHeaders
|
|
11
|
+
} from './common';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
interface IChunkCallBackArgs { data: ArrayBuffer }
|
|
15
|
+
|
|
16
|
+
interface IRequestTask {
|
|
17
|
+
abort: () => void;
|
|
18
|
+
onHeadersReceived: (callback: (res: IHeaderCallBackArgs) => void) => void;
|
|
19
|
+
offHeadersReceived: (callback?: (res: IHeaderCallBackArgs) => void) => void;
|
|
20
|
+
onChunkReceived: (callback: (res: IChunkCallBackArgs) => void) => void;
|
|
21
|
+
offChunkReceived: (callback?: (res: IChunkCallBackArgs) => void) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ISuccessCallbackResult {
|
|
25
|
+
data: TaroAny;
|
|
26
|
+
statusCode: number;
|
|
27
|
+
header: Record<string, string>;
|
|
28
|
+
errMsg: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface IRequestOptions {
|
|
32
|
+
url: string;
|
|
33
|
+
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
34
|
+
data?: TaroAny;
|
|
35
|
+
header?: Record<string, string>;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
dataType?: 'json' | 'text';
|
|
38
|
+
success?: (res: ISuccessCallbackResult) => void;
|
|
39
|
+
fail?: (res: IGeneralCallbackResult) => void;
|
|
40
|
+
complete?: (res: IGeneralCallbackResult) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default function handleRequestRcp(optionss: IEtsMethodsOptions): IRequestTask {
|
|
44
|
+
const option = (optionss?.args?.[0] || {}) as IRequestOptions
|
|
45
|
+
|
|
46
|
+
const session = rcp.createSession();
|
|
47
|
+
const method = (option.method || 'GET').toUpperCase() as rcp.HttpMethod;
|
|
48
|
+
const request = new rcp.Request(option.url, method);
|
|
49
|
+
|
|
50
|
+
// 设置请求配置
|
|
51
|
+
if (option.timeout) {
|
|
52
|
+
request.configuration = {
|
|
53
|
+
transfer: {
|
|
54
|
+
timeout: {
|
|
55
|
+
transferMs: option.timeout
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 设置请求头
|
|
62
|
+
request.headers = option.header || {};
|
|
63
|
+
|
|
64
|
+
// 处理请求数据
|
|
65
|
+
if (option.data) {
|
|
66
|
+
if (method === 'GET') {
|
|
67
|
+
// GET 请求处理查询参数
|
|
68
|
+
const params = new url.URLParams();
|
|
69
|
+
Object.keys(option.data).forEach(key => {
|
|
70
|
+
params.append(key, option.data![key]);
|
|
71
|
+
});
|
|
72
|
+
request.url.search = params.toString();
|
|
73
|
+
} else {
|
|
74
|
+
// 处理 POST/PUT 等请求体
|
|
75
|
+
const contentType = request.headers?.['Content-Type'] || 'application/json';
|
|
76
|
+
|
|
77
|
+
if (typeof option.data === 'string') {
|
|
78
|
+
request.content = option.data;
|
|
79
|
+
} else if (option.data instanceof ArrayBuffer) {
|
|
80
|
+
request.content = option.data;
|
|
81
|
+
} else {
|
|
82
|
+
// 对象类型数据序列化
|
|
83
|
+
request.content = contentType.includes('json')
|
|
84
|
+
? JSON.stringify(option.data)
|
|
85
|
+
: new url.URLParams();
|
|
86
|
+
(option.data).toString();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 设置内容类型头
|
|
90
|
+
if (!request.headers?.['Content-Type']) {
|
|
91
|
+
request.headers['Content-Type'] = contentType;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 事件处理器配置
|
|
97
|
+
let chunkCallbacks: Array<(res: IChunkCallBackArgs) => void> = [];
|
|
98
|
+
let headersCallbacks: Array<(res: IHeaderCallBackArgs) => void> = [];
|
|
99
|
+
let responseBuffer: ArrayBuffer[] = []; // 新增缓冲区存储分块数据
|
|
100
|
+
|
|
101
|
+
if (request.configuration) {
|
|
102
|
+
const tracingConfig = request.configuration.tracing ??= {};
|
|
103
|
+
const httpEvents = tracingConfig.httpEventsHandler ??= {};
|
|
104
|
+
|
|
105
|
+
httpEvents.onHeaderReceive = (headers: rcp.ResponseHeaders) => {
|
|
106
|
+
const converted: IHeaderCallBackArgs = {
|
|
107
|
+
header: convertHeaders(headers)
|
|
108
|
+
};
|
|
109
|
+
headersCallbacks.forEach(callback => callback(converted));
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// 添加分块数据接收处理
|
|
113
|
+
httpEvents.onDataReceive = (incomingData: ArrayBuffer) => {
|
|
114
|
+
// 新增分块数据缓冲
|
|
115
|
+
responseBuffer.push(incomingData);
|
|
116
|
+
|
|
117
|
+
chunkCallbacks.forEach(callback => {
|
|
118
|
+
const res: IChunkCallBackArgs = { data: incomingData }
|
|
119
|
+
callback(res);
|
|
120
|
+
});
|
|
121
|
+
return incomingData.byteLength;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 发起请求
|
|
126
|
+
session.fetch(request)
|
|
127
|
+
.then(response => {
|
|
128
|
+
let responseData: TaroAny;
|
|
129
|
+
|
|
130
|
+
// 处理响应数据(改为使用缓冲数据)
|
|
131
|
+
if (responseBuffer.length > 0) {
|
|
132
|
+
const totalLength = responseBuffer.reduce((sum, buf) => sum + buf.byteLength, 0);
|
|
133
|
+
const mergedBuffer = new Uint8Array(totalLength);
|
|
134
|
+
let offset = 0;
|
|
135
|
+
|
|
136
|
+
responseBuffer.forEach(buf => {
|
|
137
|
+
mergedBuffer.set(new Uint8Array(buf), offset);
|
|
138
|
+
offset += buf.byteLength;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// 处理分块编码(示例响应中包含 chunked 数据)
|
|
142
|
+
const rawData = new util.TextDecoder().decodeToString(mergedBuffer);
|
|
143
|
+
const cleanedData = rawData.replace(/^b\r\n|\r\n0$/, ''); // 移除chunked头尾
|
|
144
|
+
|
|
145
|
+
if (option.dataType === 'json') {
|
|
146
|
+
try {
|
|
147
|
+
responseData = JSON.parse(rawData);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
console.warn('JSON parse failed:', e);
|
|
150
|
+
responseData = rawData;
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
responseData = cleanedData; // 直接使用处理后的字符串
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const result: ISuccessCallbackResult = {
|
|
158
|
+
data: responseData,
|
|
159
|
+
statusCode: response.statusCode,
|
|
160
|
+
header: convertHeaders(response.headers),
|
|
161
|
+
errMsg: 'request:ok'
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
option.success?.(result);
|
|
165
|
+
option.complete?.({
|
|
166
|
+
errMsg: 'request:ok'
|
|
167
|
+
});
|
|
168
|
+
return result;
|
|
169
|
+
})
|
|
170
|
+
.catch((error: TaroAny) => {
|
|
171
|
+
const errMsg = `request:fail ${error.message || ''}`;
|
|
172
|
+
option.fail?.({
|
|
173
|
+
errMsg
|
|
174
|
+
});
|
|
175
|
+
option.complete?.({
|
|
176
|
+
errMsg
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 返回任务对象
|
|
181
|
+
const requestTask: IRequestTask = {
|
|
182
|
+
abort: () => session.cancel(request),
|
|
183
|
+
onHeadersReceived: (callback) => {
|
|
184
|
+
headersCallbacks.push(callback);
|
|
185
|
+
},
|
|
186
|
+
offHeadersReceived: (callback?) => {
|
|
187
|
+
if (callback) {
|
|
188
|
+
headersCallbacks = headersCallbacks.filter(cb => cb !== callback);
|
|
189
|
+
} else {
|
|
190
|
+
headersCallbacks = [];
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
onChunkReceived: (callback) => {
|
|
194
|
+
chunkCallbacks.push(callback);
|
|
195
|
+
},
|
|
196
|
+
offChunkReceived: (callback?) => {
|
|
197
|
+
if (callback) {
|
|
198
|
+
chunkCallbacks = chunkCallbacks.filter(cb => cb !== callback);
|
|
199
|
+
} else {
|
|
200
|
+
chunkCallbacks = [];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
return requestTask;
|
|
206
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { IEtsMethodsOptions } from '../../index'
|
|
2
|
+
import type { TaroAny } from '../../../../../../runtime'
|
|
3
|
+
|
|
4
|
+
import { rcp } from '@kit.RemoteCommunicationKit';
|
|
5
|
+
import { util } from '@kit.ArkTS';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
IGeneralCallbackResult,
|
|
9
|
+
IHeaderCallBackArgs,
|
|
10
|
+
IProgressCallbackArgs,
|
|
11
|
+
convertHeaders
|
|
12
|
+
} from './common';
|
|
13
|
+
|
|
14
|
+
interface IUploadTask {
|
|
15
|
+
abort: () => void;
|
|
16
|
+
onProgressUpdate: (callback: (res: IProgressCallbackArgs) => void) => void;
|
|
17
|
+
offProgressUpdate: (callback?: (res: IProgressCallbackArgs) => void) => void;
|
|
18
|
+
onHeadersReceived: (callback: (res: IHeaderCallBackArgs) => void) => void;
|
|
19
|
+
offHeadersReceived: (callback?: (res: IHeaderCallBackArgs) => void) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ISuccessCallbackResult {
|
|
23
|
+
data: string;
|
|
24
|
+
statusCode: number;
|
|
25
|
+
header: Record<string, string>;
|
|
26
|
+
errMsg: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
interface IOptions {
|
|
33
|
+
url: string;
|
|
34
|
+
filePath: string;
|
|
35
|
+
name: string;
|
|
36
|
+
header?: Record<string, string>;
|
|
37
|
+
formData?: Record<string, TaroAny>;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
success?: (res: ISuccessCallbackResult) => void;
|
|
40
|
+
fail?: (res: IGeneralCallbackResult) => void;
|
|
41
|
+
complete?: (res: IGeneralCallbackResult) => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
export default function handleUploadFileRcp(optionss: IEtsMethodsOptions): IUploadTask {
|
|
47
|
+
const option = (optionss?.args?.[0] || {}) as IOptions
|
|
48
|
+
|
|
49
|
+
// 创建一个RCP会话
|
|
50
|
+
const session = rcp.createSession();
|
|
51
|
+
|
|
52
|
+
// 创建一个request对象
|
|
53
|
+
const request = new rcp.Request(option.url, 'POST');
|
|
54
|
+
|
|
55
|
+
// 设置超时
|
|
56
|
+
if (option.timeout) {
|
|
57
|
+
request.configuration = {
|
|
58
|
+
transfer: {
|
|
59
|
+
timeout: {
|
|
60
|
+
transferMs: option.timeout
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 设置header
|
|
67
|
+
if (option.header) {
|
|
68
|
+
request.headers = option.header;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 创建表单数据
|
|
72
|
+
const formFields: rcp.MultipartFormFields = {};
|
|
73
|
+
|
|
74
|
+
// 添加formData字段
|
|
75
|
+
if (option.formData) {
|
|
76
|
+
Object.keys(option.formData).forEach(key => {
|
|
77
|
+
formFields[key] = option.formData![key];
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 添加文件字段
|
|
82
|
+
formFields[option.name] = {
|
|
83
|
+
contentType: 'application/octet-stream',
|
|
84
|
+
remoteFileName: option.filePath.split('/').pop() || 'file',
|
|
85
|
+
contentOrPath: option.filePath
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// 设置请求内容为MultipartForm
|
|
89
|
+
request.content = new rcp.MultipartForm(formFields);
|
|
90
|
+
|
|
91
|
+
// 改为使用数组存储回调
|
|
92
|
+
let progressCallbacks: Array<(res: IProgressCallbackArgs) => void> = [];
|
|
93
|
+
let headersCallbacks: Array<(res: IHeaderCallBackArgs) => void> = [];
|
|
94
|
+
|
|
95
|
+
// 设置事件处理器
|
|
96
|
+
if (request.configuration) {
|
|
97
|
+
const tracingConfig = request.configuration.tracing ??= {};
|
|
98
|
+
const httpEvents = tracingConfig.httpEventsHandler ??= {};
|
|
99
|
+
|
|
100
|
+
httpEvents.onUploadProgress = (totalSize, transferredSize) => {
|
|
101
|
+
const progress = Math.floor((transferredSize / totalSize) * 100);
|
|
102
|
+
progressCallbacks.forEach(callback => {
|
|
103
|
+
callback({
|
|
104
|
+
progress
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
httpEvents.onHeaderReceive = (headers: rcp.ResponseHeaders) => {
|
|
110
|
+
const converted: IHeaderCallBackArgs = {
|
|
111
|
+
header: convertHeaders(headers)
|
|
112
|
+
};
|
|
113
|
+
headersCallbacks.forEach(callback => {
|
|
114
|
+
callback(converted);
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
// 发起请求并处理响应
|
|
121
|
+
session.fetch(request)
|
|
122
|
+
.then(response => {
|
|
123
|
+
const result: ISuccessCallbackResult = {
|
|
124
|
+
data: response.body ? new util.TextDecoder().decodeToString(new Uint8Array(response.body)) : '',
|
|
125
|
+
statusCode: response.statusCode,
|
|
126
|
+
header: convertHeaders(response.headers),
|
|
127
|
+
errMsg: 'uploadFile:ok'
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
if (option.success) {
|
|
131
|
+
option.success(result);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (option.complete) {
|
|
135
|
+
option.complete({
|
|
136
|
+
errMsg: 'uploadFile:ok'
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
})
|
|
142
|
+
.catch((error: TaroAny) => {
|
|
143
|
+
const errMsg = `uploadFile:fail ${error.message || ''}`;
|
|
144
|
+
|
|
145
|
+
if (option.fail) {
|
|
146
|
+
option.fail({
|
|
147
|
+
errMsg
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (option.complete) {
|
|
152
|
+
option.complete({
|
|
153
|
+
errMsg
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// throw error;
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
// 返回任务对象
|
|
163
|
+
const uploadTask: IUploadTask = {
|
|
164
|
+
abort: () => {
|
|
165
|
+
session.cancel(request);
|
|
166
|
+
},
|
|
167
|
+
onProgressUpdate: (callback) => {
|
|
168
|
+
progressCallbacks.push(callback);
|
|
169
|
+
},
|
|
170
|
+
offProgressUpdate: (callback?) => {
|
|
171
|
+
if (callback) {
|
|
172
|
+
progressCallbacks = progressCallbacks.filter(cb => cb !== callback);
|
|
173
|
+
} else {
|
|
174
|
+
progressCallbacks = [];
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
onHeadersReceived: (callback) => {
|
|
178
|
+
headersCallbacks.push(callback);
|
|
179
|
+
},
|
|
180
|
+
offHeadersReceived: (callback?) => {
|
|
181
|
+
if (callback) {
|
|
182
|
+
headersCallbacks = headersCallbacks.filter(cb => cb !== callback);
|
|
183
|
+
} else {
|
|
184
|
+
headersCallbacks = [];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return uploadTask;
|
|
190
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
|
|
2
|
+
import type { TaroAny } from '../../../../../runtime'
|
|
3
|
+
import type { IEtsMethodsOptions } from '../index'
|
|
4
|
+
import router from '@ohos.router'
|
|
5
|
+
import { queryToJson } from '../../../../../shared'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function handleRoute (option: IEtsMethodsOptions) {
|
|
9
|
+
const arg: TaroAny = option.args?.[0] || {}
|
|
10
|
+
|
|
11
|
+
// 新增 URL 解析逻辑
|
|
12
|
+
const parser = parseURL(arg.url)
|
|
13
|
+
const url = parser[0]
|
|
14
|
+
const params = parser[1]
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
switch (option.name) {
|
|
18
|
+
case 'navigateTo':
|
|
19
|
+
router.pushUrl({
|
|
20
|
+
url: url,
|
|
21
|
+
params: params
|
|
22
|
+
}, (err) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
option.errorHandler?.({
|
|
25
|
+
errCode: err.code,
|
|
26
|
+
errMsg: err.message,
|
|
27
|
+
data: err.data
|
|
28
|
+
})
|
|
29
|
+
} else {
|
|
30
|
+
option.successHandler?.()
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
break
|
|
34
|
+
case 'redirectTo':
|
|
35
|
+
router.replaceUrl({
|
|
36
|
+
url: url,
|
|
37
|
+
params: params
|
|
38
|
+
}, (err) => {
|
|
39
|
+
if (err) {
|
|
40
|
+
option.errorHandler?.({
|
|
41
|
+
errCode: err.code,
|
|
42
|
+
errMsg: err.message,
|
|
43
|
+
data: err.data
|
|
44
|
+
})
|
|
45
|
+
} else {
|
|
46
|
+
option.successHandler?.()
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
break
|
|
50
|
+
case 'navigateBack':
|
|
51
|
+
if (!url) {
|
|
52
|
+
router.back()
|
|
53
|
+
} else {
|
|
54
|
+
router.back({ url })
|
|
55
|
+
}
|
|
56
|
+
option.successHandler?.()
|
|
57
|
+
break
|
|
58
|
+
case 'switchTab':
|
|
59
|
+
router.replaceUrl({
|
|
60
|
+
url: url,
|
|
61
|
+
params: params
|
|
62
|
+
}, (err) => {
|
|
63
|
+
if (err) {
|
|
64
|
+
option.errorHandler?.({
|
|
65
|
+
errCode: err.code,
|
|
66
|
+
errMsg: err.message,
|
|
67
|
+
data: err.data
|
|
68
|
+
})
|
|
69
|
+
} else {
|
|
70
|
+
option.successHandler?.()
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
break
|
|
74
|
+
default:
|
|
75
|
+
if (("development" as string) !== 'production') {
|
|
76
|
+
console.warn(`Unhandled route method: ${option.name}`)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} catch (e) {
|
|
80
|
+
if (("development" as string) !== 'production') console.error('Error(TaroETS):', e.message, e)
|
|
81
|
+
if (option.errorHandler) option.errorHandler({
|
|
82
|
+
errCode: e.code,
|
|
83
|
+
errMsg: e.message,
|
|
84
|
+
data: e.data,
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 新增 URL 解析函数
|
|
90
|
+
function parseURL(raw = ''): [string, Record<string, TaroAny>] {
|
|
91
|
+
// const [urlStr, queryStr = ''] = raw.split('?')
|
|
92
|
+
const splitRaw = raw.split('?')
|
|
93
|
+
const urlStr = splitRaw[0] || ''
|
|
94
|
+
const queryStr = splitRaw[1] || ''
|
|
95
|
+
const query = queryToJson(queryStr)
|
|
96
|
+
let url = urlStr.replace(/^\//, '')
|
|
97
|
+
|
|
98
|
+
// 处理相对路径逻辑
|
|
99
|
+
if (url.indexOf('.') === 0) {
|
|
100
|
+
const currentPage = router.getState()
|
|
101
|
+
const parts = currentPage.path.split('/')
|
|
102
|
+
parts.pop()
|
|
103
|
+
url.split('/').forEach((item) => {
|
|
104
|
+
item === '..' ? parts.pop() : parts.push(item)
|
|
105
|
+
})
|
|
106
|
+
url = parts.join('/')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return [url, query]
|
|
110
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { taskpool } from '@kit.ArkTS'
|
|
2
|
+
import fs from '@ohos.file.fs';
|
|
3
|
+
import image from '@ohos.multimedia.image';
|
|
4
|
+
import type { TaroAny } from '@tarojs/runtime'
|
|
5
|
+
import type { IEtsMethodsOptions } from '../index'
|
|
6
|
+
|
|
7
|
+
@Concurrent
|
|
8
|
+
function stringify (data: TaroAny) {
|
|
9
|
+
return JSON.stringify(data)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function handleTaskPoolStringify (option: IEtsMethodsOptions) {
|
|
13
|
+
const args: TaroAny = option.args
|
|
14
|
+
|
|
15
|
+
if (args) {
|
|
16
|
+
const data: TaroAny = args[0]
|
|
17
|
+
|
|
18
|
+
taskpool.execute(stringify, data)
|
|
19
|
+
.then(res => {
|
|
20
|
+
option.successHandler && option.successHandler({ data: res })
|
|
21
|
+
})
|
|
22
|
+
.catch((error: TaroAny) => {
|
|
23
|
+
option.errorHandler && option.errorHandler({
|
|
24
|
+
errCode: error?.code,
|
|
25
|
+
errMsg: error?.message,
|
|
26
|
+
data: error?.data,
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@Concurrent
|
|
33
|
+
function compressImage(data: Record<string, TaroAny>) {
|
|
34
|
+
|
|
35
|
+
const src = data[0] as string
|
|
36
|
+
const quality = (data[1] ?? 80) as number
|
|
37
|
+
const compressedWidth = data[2] as number
|
|
38
|
+
const compressedHeight = data[3] as number
|
|
39
|
+
const file = fs.openSync(src, fs.OpenMode.READ_ONLY);
|
|
40
|
+
|
|
41
|
+
const source = image.createImageSource(file.fd)
|
|
42
|
+
|
|
43
|
+
if (null === (source)) {
|
|
44
|
+
throw new Error('compressImage fail: createImageSource has failed')
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const width = source.getImageInfoSync().size.width;
|
|
48
|
+
const height = source.getImageInfoSync().size.height;
|
|
49
|
+
let wantWidth = compressedWidth || compressedHeight || 0;
|
|
50
|
+
let wantHeight = compressedHeight || compressedWidth || 0;
|
|
51
|
+
if (width > wantWidth || height > wantHeight) {
|
|
52
|
+
const heightRatio = height / wantHeight;
|
|
53
|
+
const widthRatio = width / wantWidth;
|
|
54
|
+
const finalRatio = heightRatio < widthRatio ? heightRatio : widthRatio;
|
|
55
|
+
wantWidth = Math.round(width / finalRatio);
|
|
56
|
+
wantHeight = Math.round(height / finalRatio);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const pixelMap = source.createPixelMapSync({
|
|
61
|
+
editable: true,
|
|
62
|
+
desiredPixelFormat: image.PixelMapFormat.RGBA_8888,
|
|
63
|
+
desiredSize: { width: wantWidth, height: wantHeight },
|
|
64
|
+
})
|
|
65
|
+
fs.closeSync(file);
|
|
66
|
+
return pixelMap
|
|
67
|
+
} catch (e) {
|
|
68
|
+
fs.closeSync(file);
|
|
69
|
+
throw new Error("createPixelMapSync error: ")
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function handleTaskPoolCompressImage(option: IEtsMethodsOptions) {
|
|
76
|
+
|
|
77
|
+
taskpool.execute(compressImage, option.args as Record<string, TaroAny>)
|
|
78
|
+
.then(res => {
|
|
79
|
+
option?.successHandler?.(res)
|
|
80
|
+
})
|
|
81
|
+
.catch((error: TaroAny) => {
|
|
82
|
+
option?.errorHandler?.({
|
|
83
|
+
errCode: error?.code,
|
|
84
|
+
errMsg: error,
|
|
85
|
+
data: error?.data,
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@Concurrent
|
|
93
|
+
function getImageSize(uri: string) {
|
|
94
|
+
const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
|
|
95
|
+
const stat = fs.statSync(file.fd);
|
|
96
|
+
const size = stat.size;
|
|
97
|
+
fs.closeSync(file);
|
|
98
|
+
return size
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function handleTaskPoolGetImageSize(option: IEtsMethodsOptions) {
|
|
102
|
+
const args: TaroAny = option.args
|
|
103
|
+
|
|
104
|
+
if (args) {
|
|
105
|
+
const data: TaroAny = args[0]
|
|
106
|
+
|
|
107
|
+
taskpool.execute(getImageSize, data)
|
|
108
|
+
.then(res => {
|
|
109
|
+
option.successHandler && option.successHandler({ data: res })
|
|
110
|
+
})
|
|
111
|
+
.catch((error: TaroAny) => {
|
|
112
|
+
option.errorHandler && option.errorHandler({
|
|
113
|
+
errCode: error?.code,
|
|
114
|
+
errMsg: error?.message,
|
|
115
|
+
data: error?.data,
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
export function handleTaskPool(option: IEtsMethodsOptions) {
|
|
123
|
+
const name = option.name
|
|
124
|
+
|
|
125
|
+
if (!name) {
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
switch (option.name) {
|
|
131
|
+
case 'stringify':
|
|
132
|
+
handleTaskPoolStringify(option)
|
|
133
|
+
break
|
|
134
|
+
case 'compressImage':
|
|
135
|
+
handleTaskPoolCompressImage(option)
|
|
136
|
+
break
|
|
137
|
+
case 'getImageSize':
|
|
138
|
+
handleTaskPoolGetImageSize(option)
|
|
139
|
+
break
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
if (process.env.NODE_ENV !== 'production') console.error('Error(TaroETS):', e.message, e)
|
|
143
|
+
if (option.errorHandler) option.errorHandler({
|
|
144
|
+
errCode: e.code,
|
|
145
|
+
errMsg: e.message,
|
|
146
|
+
data: e.data,
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Current, eventCenter } from '@tarojs/runtime'
|
|
2
|
+
import BuildProfile from 'BuildProfile'
|
|
3
|
+
|
|
4
|
+
import type { TaroAny } from '@tarojs/runtime'
|
|
5
|
+
|
|
6
|
+
import { handleTaskPool } from './apis/taskpool'
|
|
7
|
+
import { handleNetwork } from './apis/network/index'
|
|
8
|
+
import { handleRoute } from './apis/route'
|
|
9
|
+
|
|
10
|
+
export interface IEtsMethodsOptions {
|
|
11
|
+
methodName?: string
|
|
12
|
+
name?: string
|
|
13
|
+
scope?: string
|
|
14
|
+
type?: string
|
|
15
|
+
args?: TaroAny[]
|
|
16
|
+
successHandler?: (...args: TaroAny[]) => void
|
|
17
|
+
errorHandler?: (...args: TaroAny[]) => void
|
|
18
|
+
onInit?: (obj: TaroAny) => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Note: 监听 API 事件
|
|
22
|
+
eventCenter?.on('__taroPluginEtsMethodsTrigger', (option: IEtsMethodsOptions) => {
|
|
23
|
+
switch (option.scope) {
|
|
24
|
+
case 'route':
|
|
25
|
+
handleRoute(option)
|
|
26
|
+
break
|
|
27
|
+
case 'network':
|
|
28
|
+
handleNetwork(option)
|
|
29
|
+
break
|
|
30
|
+
case 'taskpool':
|
|
31
|
+
handleTaskPool(option)
|
|
32
|
+
break
|
|
33
|
+
default:
|
|
34
|
+
console.error(`Error(TaroETS): cannot found ${option.type} ${option.name} in ${option.scope} scope.`)
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
if (BuildProfile.DEBUG) {
|
|
39
|
+
console.log('TARO_LOG(harmony_cpp): 当前是测试环境!')
|
|
40
|
+
Current.isDebug = true
|
|
41
|
+
}
|