@jiangzhongxi0322/messagechannel 1.0.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/messageChennel.d.ts +15 -0
- package/dist/messageChennel.js +257 -0
- package/package.json +23 -0
- package/src/messageChennel.ts +251 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
interface FeedbackData {
|
|
3
|
+
code: 0 | 1 | 2;
|
|
4
|
+
msg: string;
|
|
5
|
+
data: any;
|
|
6
|
+
}
|
|
7
|
+
declare const MessageChannel: () => {
|
|
8
|
+
publish: (typename: string, msg?: any) => void;
|
|
9
|
+
subscribe: (typename: string, subscriber: (data: FeedbackData) => any, once?: boolean) => (() => void) | undefined;
|
|
10
|
+
setCarrier: (carrier: any) => void;
|
|
11
|
+
pubWithSub: (typename: string, msg: any, subscriber?: (data: FeedbackData) => any) => Promise<unknown>;
|
|
12
|
+
initiator: (viewType: string) => void;
|
|
13
|
+
getCarrier: () => vscode.Webview;
|
|
14
|
+
};
|
|
15
|
+
export default MessageChannel;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const vscode = __importStar(require("vscode"));
|
|
46
|
+
const MessageChannel = () => {
|
|
47
|
+
let cachedCarrier;
|
|
48
|
+
let dispose;
|
|
49
|
+
const setCarrier = (carrier) => {
|
|
50
|
+
if (carrier === undefined) {
|
|
51
|
+
cachedCarrier = window.acquireVsCodeApi();
|
|
52
|
+
window.addEventListener('message', (event) => {
|
|
53
|
+
messageHandler(event.data);
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (cachedCarrier) {
|
|
58
|
+
dispose.dispose();
|
|
59
|
+
}
|
|
60
|
+
cachedCarrier = carrier;
|
|
61
|
+
if (carrier === null) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
dispose = cachedCarrier.onDidReceiveMessage((event) => messageHandler(event));
|
|
65
|
+
};
|
|
66
|
+
const subscribers = {};
|
|
67
|
+
const messageHandler = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
+
const { data: feedbackData, typename } = event;
|
|
69
|
+
const data = feedbackData.data;
|
|
70
|
+
const isTalkInExtension = typename && subscribers[typename];
|
|
71
|
+
if (isTalkInExtension) {
|
|
72
|
+
subscribers[typename].forEach((resolver) => {
|
|
73
|
+
resolver(feedbackData);
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const isTalkToExtension = typename && (data === null || data === void 0 ? void 0 : data.viewType);
|
|
78
|
+
if (isTalkToExtension) {
|
|
79
|
+
const activeTargetExtension = (extensionId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
80
|
+
const targetExtension = vscode.extensions.getExtension(extensionId);
|
|
81
|
+
if (!targetExtension) {
|
|
82
|
+
console.warn(`Extension ${extensionId} not found`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (!targetExtension.isActive) {
|
|
86
|
+
yield (targetExtension === null || targetExtension === void 0 ? void 0 : targetExtension.activate());
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
});
|
|
90
|
+
if (yield activeTargetExtension(typename)) {
|
|
91
|
+
const commands = yield vscode.commands.getCommands();
|
|
92
|
+
const commandID = `to_${data.viewType}`;
|
|
93
|
+
if (commands.includes(commandID)) {
|
|
94
|
+
const talkToOtherExtension = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
const result = yield vscode.commands.executeCommand(commandID, data);
|
|
96
|
+
publish(typename, result);
|
|
97
|
+
if (result !== undefined) {
|
|
98
|
+
yield talkToOtherExtension();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
yield talkToOtherExtension();
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.warn(`Command ${commandID} not found`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
const subscribe = (typename, subscriber, once = false) => {
|
|
110
|
+
if (!subscriber || !(subscriber instanceof Function)) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const resolver = (data) => {
|
|
114
|
+
const result = subscriber(data);
|
|
115
|
+
if (result !== undefined) {
|
|
116
|
+
if (result instanceof Promise) {
|
|
117
|
+
result.then((data) => {
|
|
118
|
+
publish(typename, data);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
publish(typename, result);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (once) {
|
|
126
|
+
const subscriber = subscribers[typename];
|
|
127
|
+
if (subscriber === null || subscriber === void 0 ? void 0 : subscriber.length) {
|
|
128
|
+
const i = subscriber.indexOf(resolver);
|
|
129
|
+
subscriber.splice(i, 1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const _subscribers = subscribers;
|
|
134
|
+
if (_subscribers[typename]) {
|
|
135
|
+
_subscribers[typename].push(resolver);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
_subscribers[typename] = [resolver];
|
|
139
|
+
}
|
|
140
|
+
return () => {
|
|
141
|
+
const subscriber = subscribers[typename];
|
|
142
|
+
if (subscriber === null || subscriber === void 0 ? void 0 : subscriber.length) {
|
|
143
|
+
const i = subscriber.indexOf(resolver);
|
|
144
|
+
subscriber.splice(i, 1);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
const publish = (typename, msg) => {
|
|
149
|
+
try {
|
|
150
|
+
cachedCarrier === null || cachedCarrier === void 0 ? void 0 : cachedCarrier.postMessage({
|
|
151
|
+
typename: typename,
|
|
152
|
+
data: msg,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
0;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
// vscode.WebviewViewProvider的静态方法中调用
|
|
160
|
+
const initiator = (viewType) => {
|
|
161
|
+
// for node
|
|
162
|
+
if (viewType) {
|
|
163
|
+
vscode.commands.registerCommand(`to_${viewType}`, (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
const { source } = args;
|
|
165
|
+
const openWebview = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
+
const commands = yield vscode.commands.getCommands();
|
|
167
|
+
if (commands.includes(source)) {
|
|
168
|
+
yield vscode.commands.executeCommand(source);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
const uri = vscode.Uri.file(source);
|
|
172
|
+
if (!uri) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
yield vscode.commands.executeCommand('vscode.openWith', uri, viewType, vscode.ViewColumn.One);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
// 首次打开webview
|
|
180
|
+
subscribe('webviewRenderDone', () => {
|
|
181
|
+
pubWithSub('clickAnyElement', args, (data) => {
|
|
182
|
+
resolve(data);
|
|
183
|
+
});
|
|
184
|
+
}, true);
|
|
185
|
+
// 已经打开过webview
|
|
186
|
+
pubWithSub('clickAnyElement', args, (data) => {
|
|
187
|
+
resolve(data);
|
|
188
|
+
});
|
|
189
|
+
openWebview();
|
|
190
|
+
});
|
|
191
|
+
}));
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
publish('webviewRenderDone', null);
|
|
195
|
+
subscribe('clickAnyElement', (data) => {
|
|
196
|
+
const clickAnyElement = (data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
197
|
+
const selectorList = data === null || data === void 0 ? void 0 : data.selector;
|
|
198
|
+
let index = 0;
|
|
199
|
+
const timer = setInterval(() => {
|
|
200
|
+
var _a;
|
|
201
|
+
const allDone = index >= ((selectorList === null || selectorList === void 0 ? void 0 : selectorList.length) || 0);
|
|
202
|
+
if (allDone) {
|
|
203
|
+
clearInterval(timer);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const originSelector = selectorList === null || selectorList === void 0 ? void 0 : selectorList[index];
|
|
207
|
+
const i = originSelector === null || originSelector === void 0 ? void 0 : originSelector.split('$')[1];
|
|
208
|
+
const selector = originSelector.split('$')[0];
|
|
209
|
+
const element = (_a = window.document) === null || _a === void 0 ? void 0 : _a.querySelector(selector);
|
|
210
|
+
if (selector && element) {
|
|
211
|
+
element.dataset['payload'] = data === null || data === void 0 ? void 0 : data.payload;
|
|
212
|
+
element === null || element === void 0 ? void 0 : element.click();
|
|
213
|
+
index++;
|
|
214
|
+
}
|
|
215
|
+
}, 1000);
|
|
216
|
+
});
|
|
217
|
+
return new Promise((resolve) => {
|
|
218
|
+
window.feedbackResult = resolve;
|
|
219
|
+
clickAnyElement(data);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* key: 唯一key,插件identifier或者消息类型
|
|
225
|
+
* args: 传递的数据
|
|
226
|
+
* {
|
|
227
|
+
* viewType: 要打开的webview的类型
|
|
228
|
+
* source: webview如果是命令打开则是命令ID,如果是则是文件的绝对路径
|
|
229
|
+
* selectorList: 要点击的元素选择器列表
|
|
230
|
+
* }
|
|
231
|
+
* subscribe?: 发布后通过订阅获取反馈数据,如果没有subscribe,则可以通过异步等待获取反馈的数据
|
|
232
|
+
*
|
|
233
|
+
*/
|
|
234
|
+
const pubWithSub = (typename, msg, subscriber) => __awaiter(void 0, void 0, void 0, function* () {
|
|
235
|
+
publish(typename, msg);
|
|
236
|
+
return new Promise((resolve) => {
|
|
237
|
+
const removeSubscribe = subscribe(typename, (data) => {
|
|
238
|
+
if (subscriber) {
|
|
239
|
+
subscriber(data);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
resolve(data);
|
|
243
|
+
}
|
|
244
|
+
removeSubscribe && removeSubscribe();
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
publish,
|
|
250
|
+
subscribe,
|
|
251
|
+
setCarrier,
|
|
252
|
+
pubWithSub,
|
|
253
|
+
initiator,
|
|
254
|
+
getCarrier: () => cachedCarrier,
|
|
255
|
+
};
|
|
256
|
+
};
|
|
257
|
+
exports.default = MessageChannel;
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jiangzhongxi0322/messagechannel",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "A message channel for communication between VSCode extensions and webviews.",
|
|
8
|
+
"main": "dist/messageChennel.js",
|
|
9
|
+
"types": "dist/messageChennel.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@types/vscode": "^1.80.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.0.0"
|
|
19
|
+
},
|
|
20
|
+
"keywords": ["vscode", "message", "channel", "webview"],
|
|
21
|
+
"author": "jiangzhongxi0322",
|
|
22
|
+
"license": "MIT"
|
|
23
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
|
|
3
|
+
interface Event {
|
|
4
|
+
typename?: string;
|
|
5
|
+
key?: string;
|
|
6
|
+
channelId: string;
|
|
7
|
+
data: FeedbackData;
|
|
8
|
+
}
|
|
9
|
+
interface FeedbackData {
|
|
10
|
+
code: 0 | 1 | 2;
|
|
11
|
+
msg: string;
|
|
12
|
+
data: any;
|
|
13
|
+
}
|
|
14
|
+
// 每个vscode的node端和webview都分别拥有一个MessageChannel返回的对象,因为他们是不同载体
|
|
15
|
+
// 同一webview如果打开了多个文档,各个文档也应该有不同的载体
|
|
16
|
+
declare const window: any;
|
|
17
|
+
|
|
18
|
+
const MessageChannel = () => {
|
|
19
|
+
let cachedCarrier: vscode.Webview;
|
|
20
|
+
let dispose: vscode.Disposable;
|
|
21
|
+
|
|
22
|
+
const setCarrier = (carrier: any) => {
|
|
23
|
+
if (carrier === undefined) {
|
|
24
|
+
cachedCarrier = (window as any).acquireVsCodeApi();
|
|
25
|
+
(window as any).addEventListener('message', (event: any) => {
|
|
26
|
+
messageHandler(event.data);
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (cachedCarrier) {
|
|
31
|
+
dispose.dispose();
|
|
32
|
+
}
|
|
33
|
+
cachedCarrier = carrier;
|
|
34
|
+
if (carrier === null) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
dispose = cachedCarrier.onDidReceiveMessage((event) =>
|
|
38
|
+
messageHandler(event)
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const subscribers: {
|
|
43
|
+
[i: string]: ((data: any) => void)[];
|
|
44
|
+
} = {};
|
|
45
|
+
|
|
46
|
+
const messageHandler = async (event: Event) => {
|
|
47
|
+
const { data: feedbackData, typename } = event;
|
|
48
|
+
const data = feedbackData.data;
|
|
49
|
+
const isTalkInExtension = typename && subscribers[typename];
|
|
50
|
+
if (isTalkInExtension) {
|
|
51
|
+
subscribers[typename as string].forEach((resolver) => {
|
|
52
|
+
resolver(feedbackData);
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const isTalkToExtension = typename && data?.viewType;
|
|
57
|
+
if(isTalkToExtension) {
|
|
58
|
+
const activeTargetExtension = async (extensionId: string) => {
|
|
59
|
+
const targetExtension = vscode.extensions.getExtension(extensionId);
|
|
60
|
+
if(!targetExtension ) {
|
|
61
|
+
console.warn(`Extension ${extensionId} not found`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if(!targetExtension.isActive) {
|
|
65
|
+
await targetExtension?.activate();
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
};
|
|
69
|
+
if(await activeTargetExtension(typename)) {
|
|
70
|
+
const commands = await vscode.commands.getCommands();
|
|
71
|
+
const commandID = `to_${data.viewType}`;
|
|
72
|
+
if(commands.includes(commandID)) {
|
|
73
|
+
const talkToOtherExtension = async () => {
|
|
74
|
+
const result = await vscode.commands.executeCommand(commandID, data);
|
|
75
|
+
publish(typename, result);
|
|
76
|
+
if (result !== undefined) {
|
|
77
|
+
await talkToOtherExtension();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
await talkToOtherExtension();
|
|
81
|
+
} else {
|
|
82
|
+
console.warn(`Command ${commandID} not found`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
};
|
|
89
|
+
const subscribe = (
|
|
90
|
+
typename: string,
|
|
91
|
+
subscriber: (data: FeedbackData) => any,
|
|
92
|
+
once = false
|
|
93
|
+
) => {
|
|
94
|
+
if (!subscriber || !(subscriber instanceof Function)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const resolver = (data: FeedbackData) => {
|
|
98
|
+
const result = subscriber(data);
|
|
99
|
+
if (result !== undefined) {
|
|
100
|
+
if (result instanceof Promise) {
|
|
101
|
+
result.then((data) => {
|
|
102
|
+
publish(typename, data);
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
publish(typename, result);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (once) {
|
|
109
|
+
const subscriber = subscribers[typename];
|
|
110
|
+
if (subscriber?.length) {
|
|
111
|
+
const i = subscriber.indexOf(resolver);
|
|
112
|
+
subscriber.splice(i, 1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const _subscribers = subscribers;
|
|
117
|
+
if (_subscribers[typename]) {
|
|
118
|
+
_subscribers[typename].push(resolver);
|
|
119
|
+
} else {
|
|
120
|
+
_subscribers[typename] = [resolver];
|
|
121
|
+
}
|
|
122
|
+
return () => {
|
|
123
|
+
const subscriber = subscribers[typename];
|
|
124
|
+
if (subscriber?.length) {
|
|
125
|
+
const i = subscriber.indexOf(resolver);
|
|
126
|
+
subscriber.splice(i, 1);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const publish = (typename: string, msg?: any) => {
|
|
132
|
+
try {
|
|
133
|
+
cachedCarrier?.postMessage({
|
|
134
|
+
typename: typename,
|
|
135
|
+
data: msg,
|
|
136
|
+
});
|
|
137
|
+
} catch (error) {0;}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
// vscode.WebviewViewProvider的静态方法中调用
|
|
142
|
+
const initiator = (viewType: string) => {
|
|
143
|
+
// for node
|
|
144
|
+
if(viewType) {
|
|
145
|
+
vscode.commands.registerCommand(`to_${viewType}`, async (args) => {
|
|
146
|
+
const { source } = args;
|
|
147
|
+
const openWebview = async () => {
|
|
148
|
+
const commands = await vscode.commands.getCommands();
|
|
149
|
+
if(commands.includes(source)) {
|
|
150
|
+
await vscode.commands.executeCommand(source);
|
|
151
|
+
} else {
|
|
152
|
+
const uri = vscode.Uri.file(source);
|
|
153
|
+
if(!uri) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
await vscode.commands.executeCommand(
|
|
157
|
+
'vscode.openWith',
|
|
158
|
+
uri,
|
|
159
|
+
viewType,
|
|
160
|
+
vscode.ViewColumn.One
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return new Promise((resolve) => { // 通过这个返回数据源
|
|
166
|
+
// 首次打开webview
|
|
167
|
+
subscribe('webviewRenderDone', () => {
|
|
168
|
+
pubWithSub('clickAnyElement', args, (data) => {
|
|
169
|
+
resolve(data);
|
|
170
|
+
});
|
|
171
|
+
}, true);
|
|
172
|
+
// 已经打开过webview
|
|
173
|
+
pubWithSub('clickAnyElement', args, (data) => {
|
|
174
|
+
resolve(data);
|
|
175
|
+
});
|
|
176
|
+
openWebview();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
publish('webviewRenderDone', null);
|
|
182
|
+
subscribe('clickAnyElement', (data) => {
|
|
183
|
+
const clickAnyElement = async (data: any) => {
|
|
184
|
+
const selectorList = data?.selector;
|
|
185
|
+
let index = 0;
|
|
186
|
+
const timer = setInterval(() => {
|
|
187
|
+
const allDone = index >= (selectorList?.length || 0);
|
|
188
|
+
if(allDone) {
|
|
189
|
+
clearInterval(timer);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const originSelector = selectorList?.[index];
|
|
194
|
+
const i = originSelector?.split('$')[1];
|
|
195
|
+
const selector =originSelector.split('$')[0];
|
|
196
|
+
const element = (window as any).document?.querySelector(selector);
|
|
197
|
+
|
|
198
|
+
if(selector && element) {
|
|
199
|
+
element.dataset['payload'] = data?.payload;
|
|
200
|
+
element?.click();
|
|
201
|
+
index++;
|
|
202
|
+
}
|
|
203
|
+
}, 1000);
|
|
204
|
+
};
|
|
205
|
+
return new Promise((resolve) => {
|
|
206
|
+
window.feedbackResult = resolve;
|
|
207
|
+
clickAnyElement(data);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* key: 唯一key,插件identifier或者消息类型
|
|
213
|
+
* args: 传递的数据
|
|
214
|
+
* {
|
|
215
|
+
* viewType: 要打开的webview的类型
|
|
216
|
+
* source: webview如果是命令打开则是命令ID,如果是则是文件的绝对路径
|
|
217
|
+
* selectorList: 要点击的元素选择器列表
|
|
218
|
+
* }
|
|
219
|
+
* subscribe?: 发布后通过订阅获取反馈数据,如果没有subscribe,则可以通过异步等待获取反馈的数据
|
|
220
|
+
*
|
|
221
|
+
*/
|
|
222
|
+
const pubWithSub = async (
|
|
223
|
+
typename: string,
|
|
224
|
+
msg: any,
|
|
225
|
+
subscriber?: (data: FeedbackData) => any
|
|
226
|
+
) => {
|
|
227
|
+
publish(typename, msg);
|
|
228
|
+
|
|
229
|
+
return new Promise((resolve) => {
|
|
230
|
+
const removeSubscribe = subscribe(typename, (data: FeedbackData) => {
|
|
231
|
+
if (subscriber) {
|
|
232
|
+
subscriber(data);
|
|
233
|
+
} else {
|
|
234
|
+
resolve(data);
|
|
235
|
+
}
|
|
236
|
+
removeSubscribe && removeSubscribe();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
publish,
|
|
243
|
+
subscribe,
|
|
244
|
+
setCarrier,
|
|
245
|
+
pubWithSub,
|
|
246
|
+
initiator,
|
|
247
|
+
getCarrier: () => cachedCarrier,
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
export default MessageChannel;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES6",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"lib": ["es2016", "dom"]
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*"],
|
|
15
|
+
"exclude": ["node_modules"]
|
|
16
|
+
}
|