• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16// The module 'vscode' contains the VS Code extensibility API
17// Import the module and reference it with the alias vscode in your code below
18const vscode = require('vscode');
19const fs = require('fs');
20const re = require("./gen/tools/VsPluginRe");
21const { VsPluginLog } = require("./gen/tools/VsPluginLog");
22const { detectPlatform, readFile } = require('./gen/tools/VsPluginTool');
23const path = require('path');
24var exeFilePath = null;
25// this method is called when your extension is activated
26// your extension is activated the very first time the command is executed
27
28/**
29 * @param {vscode.ExtensionContext} context
30 */
31function activate(context) {
32	// Use the console to output diagnostic information (console.log) and errors (console.error)
33	// This line of code will only be executed once when your extension is activated
34	console.log('Congratulations, your extension "gnapi" is now active!');
35	let disposable = register(context, 'generate_napi');
36	let disposableMenu = register(context, 'generate_napi_menu');
37	context.subscriptions.push(disposable);
38	context.subscriptions.push(disposableMenu);
39	var platform = detectPlatform();
40	if (platform == 'win') {
41		exeFilePath = __dirname + "/napi_generator-win.exe";
42	} else if (platform == 'mac') {
43		exeFilePath = __dirname + "/napi_generator-macos";
44	} else if (platform == 'Linux') {
45		exeFilePath = __dirname + "/napi_generator-linux";
46	}
47}
48
49function executor(name, genDir, mode, importIsCheck) {
50	var exec = require('child_process').exec;
51	exec(genCommand(name, genDir, mode, importIsCheck), function (error, stdout, stderr) {
52		VsPluginLog.logInfo('VsPlugin: stdout =' + stdout + ", stderr =" + stderr);
53		if (error || stdout.indexOf("success") < 0) {
54			vscode.window.showErrorMessage("genError:" + (error != null ? error : "") + stdout);
55			return VsPluginLog.logError("VsPlugin:" + error + stdout);
56		}
57		vscode.window.showInformationMessage("Generated successfully");
58	});
59}
60
61function genCommand(name, genDir, mode, importIsCheck) {
62	var genFileMode = mode == 0 ? " -f " : " -d ";
63	if (genDir == ""){
64		return exeFilePath + genFileMode + name;
65	}
66	return exeFilePath + genFileMode + name + " -o " + genDir + " -i " + importIsCheck;
67}
68
69function exeFileExit() {
70	if (fs.existsSync(exeFilePath)) {
71		return true;
72	}
73	return false;
74}
75
76function register(context, command) {
77	let disposable = vscode.commands.registerCommand(command, function (uri) {
78		// The code you place here will be executed every time your command is executed
79		// Display a message box to the user
80		const panel = vscode.window.createWebviewPanel(
81			'generate', // Identifies the type of WebView
82			'Generate Napi Frame', // Title of the panel displayed to the user
83			vscode.ViewColumn.Two, // Display the WebView panel in the form of new columns in the editor
84			{
85				enableScripts: true, // Enable or disable JS, default is Enable
86				retainContextWhenHidden: true, // Keep the WebView state when it is hidden to avoid being reset
87			}
88		);
89		panel.webview.html = getWebviewContent(context);
90		panel.webview.onDidReceiveMessage(message => {
91			let msg = message.msg;
92			if (msg == "cancel") {
93				panel.dispose();
94			} else if(msg == "param") {
95				let mode = message.mode;
96				let name = message.fileNames;
97				let genDir = message.genDir;
98				let importIsCheck = message.importIsCheck;
99				checkMode(name, genDir, mode, importIsCheck);
100			} else {
101				selectPath(panel, message);
102			}
103		}, undefined, context.subscriptions);
104		let fn = re.getFileInPath(uri.fsPath);
105		let tt = re.match("@ohos.[a-zA-Z_0-9]+.d.ts", fn);
106		var result = {
107			msg: "selectInterPath",
108			path: tt ? uri.fsPath : ""
109			}
110	    panel.webview.postMessage(result);
111	});
112	return disposable;
113}
114
115/**
116* 选择本地目录/文件夹
117*/
118 function selectPath(panel, message) {
119	let mode = 1;
120	if (message.mode != undefined) {
121		mode = message.mode;
122	}
123	const options = {
124		canSelectMany: mode == 0 ? true : false,//是否可以选择多个
125		openLabel: mode == 0 ? '选择文件' : '选择文件夹',//打开选择的右下角按钮label
126		canSelectFiles: mode == 0 ? true : false,//是否选择文件
127		canSelectFolders: mode == 0 ? false : true,//是否选择文件夹
128		defaultUri:vscode.Uri.file(''),//默认打开本地路径
129		filters: {
130			'Text files': ['d.ts']
131		}
132	};
133
134	return vscode.window.showOpenDialog(options).then(fileUri => {
135	   if (fileUri && fileUri[0]) {
136		   console.log('Selected file: ' + fileUri[0].fsPath);
137		   let filePath = "";
138		   for (let index = 0; index < fileUri.length; index++) {
139				filePath += fileUri[index].fsPath.concat(",");
140		   }
141		   var result = {
142				msg: message.msg,
143				path: filePath.length > 0 ? filePath.substring(0, filePath.length - 1) : filePath
144				}
145		   panel.webview.postMessage(result);
146		   return fileUri[0].fsPath
147	   }
148   });
149}
150
151function checkMode(name, genDir, mode, importIsCheck) {
152	name = re.replaceAll(name, " ", "");
153	if ("" == name) {
154		vscode.window.showErrorMessage("Please enter the path!");
155		return;
156	}
157	if (mode == 0) {
158		if (name.indexOf(".") < 0) {
159			vscode.window.showErrorMessage("Please enter the correct file path!");
160			return;
161		}
162	} else {
163		if (name.indexOf(".") > 0 || !fs.lstatSync(name).isDirectory()) {
164			vscode.window.showErrorMessage("Please enter the correct folder folder!");
165			return;
166		}
167	}
168	if (exeFileExit()) {
169		executor(name, genDir, mode, importIsCheck);
170	} else {
171		vscode.window.showInformationMessage("Copy executable program to " + __dirname);
172	}
173}
174
175// this method is called when your extension is deactivated
176function deactivate() { }
177
178function getWebviewContent(context) {
179	let data = readFile(__dirname + '/vs_plugin_view.html');
180	data = getWebViewContent(context, '/vs_plugin_view.html');
181	return data.toString();
182}
183
184function getWebViewContent(context, templatePath) {
185    const resourcePath = path.join(context.extensionPath, templatePath);
186    const dirPath = path.dirname(resourcePath);
187    let html = fs.readFileSync(resourcePath, 'utf-8');
188    html = html.replace(/(<link.+?href="|<script.+?src="|<iframe.+?src="|<img.+?src=")(.+?)"/g, (m, $1, $2) => {
189        if($2.indexOf("https://")<0)return $1 + vscode.Uri.file(path.resolve(dirPath, $2))
190		.with({ scheme: 'vscode-resource' }).toString() + '"';
191        else return $1 + $2+'"';
192    });
193    return html;
194}
195
196module.exports = {
197	activate,
198	deactivate
199}