新增了Http请求ServiceDemo,新增了在Editor视图中嵌入webview,问题在于内核和浏览器之间的文件引用的环境处理太麻烦了,目前只能做到直接硬编码一整个HTML或者HTML读成文本,第二种方式还没找到怎么启用js
Some checks failed
Monaco Editor checks / Monaco Editor checks (push) Failing after 16m53s
Some checks failed
Monaco Editor checks / Monaco Editor checks (push) Failing after 16m53s
This commit is contained in:
parent
2062121cb9
commit
d9bac9bc6c
@ -2,50 +2,291 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
// import { EditorPane } from '../../../../browser/parts/editor/editorPane.js';
|
||||||
|
// import { Dimension } from '../../../../../base/browser/dom.js';
|
||||||
|
// import { StockDetailsInput } from './StockDetailsInput.js';
|
||||||
|
// import { IWebviewService, IOverlayWebview } from '../../../../contrib/webview/browser/webview.js';
|
||||||
|
// import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';
|
||||||
|
// import { IThemeService } from '../../../../../platform/theme/common/themeService.js';
|
||||||
|
// import { IStorageService } from '../../../../../platform/storage/common/storage.js';
|
||||||
|
// import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
||||||
|
// import { IEditorOptions } from '../../../../../platform/editor/common/editor.js';
|
||||||
|
// import { IEditorOpenContext } from '../../../../common/editor.js';
|
||||||
|
// import { IEditorGroup } from '../../../../services/editor/common/editorGroupsService.js';
|
||||||
|
// import * as DOM from '../../../../../base/browser/dom.js';
|
||||||
|
|
||||||
|
// export class StockDetailsEditor extends EditorPane {
|
||||||
|
// static readonly ID = 'workbench.editor.stockDetails';
|
||||||
|
|
||||||
|
// private webview: IOverlayWebview | null = null;
|
||||||
|
|
||||||
|
// constructor(
|
||||||
|
// group: IEditorGroup,
|
||||||
|
// @ITelemetryService telemetryService: ITelemetryService,
|
||||||
|
// @IThemeService themeService: IThemeService,
|
||||||
|
// @IStorageService storageService: IStorageService,
|
||||||
|
// @IWebviewService private readonly webviewService: IWebviewService
|
||||||
|
// ) {
|
||||||
|
// super(StockDetailsEditor.ID, group, telemetryService, themeService, storageService);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 创建编辑器容器并初始化 WebView。
|
||||||
|
// */
|
||||||
|
// protected createEditor(parent: HTMLElement): void {
|
||||||
|
// // 使用 WebView 服务创建 IOverlayWebview 实例
|
||||||
|
// this.webview = this.webviewService.createWebviewOverlay({
|
||||||
|
// providedViewType: 'stockDetailsEditor',
|
||||||
|
// title: '股票详情',
|
||||||
|
// options: { retainContextWhenHidden: true },
|
||||||
|
// contentOptions: {
|
||||||
|
// allowScripts: true,
|
||||||
|
// localResourceRoots: [], // 根据需求设置本地资源根路径
|
||||||
|
// },
|
||||||
|
// extension: undefined,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // 将 WebView 定位到父元素
|
||||||
|
// if (this.webview) {
|
||||||
|
// // 获取当前激活的窗口
|
||||||
|
// const targetWindow = DOM.getActiveWindow();
|
||||||
|
|
||||||
|
// if (!targetWindow) {
|
||||||
|
// console.error('无法获取活动窗口');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Claim WebView 所有权,绑定到目标窗口
|
||||||
|
// this.webview.claim(this, targetWindow as any, undefined);
|
||||||
|
|
||||||
|
// // 使用 layoutWebviewOverElement 方法,将 WebView 定位到 `parent`
|
||||||
|
// this.webview.layoutWebviewOverElement(parent, new Dimension(parent.offsetWidth, parent.offsetHeight));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 设置编辑器输入并更新 WebView 内容。
|
||||||
|
// */
|
||||||
|
// override async setInput(
|
||||||
|
// input: StockDetailsInput,
|
||||||
|
// options: IEditorOptions | undefined,
|
||||||
|
// context: IEditorOpenContext,
|
||||||
|
// token: CancellationToken
|
||||||
|
// ): Promise<void> {
|
||||||
|
// await super.setInput(input, options, context, token);
|
||||||
|
|
||||||
|
// if (this.webview && input.resource) {
|
||||||
|
// const stockCode = input.getCode();
|
||||||
|
|
||||||
|
// if (!stockCode || stockCode.trim() === '') {
|
||||||
|
// this.renderErrorMessage('股票代码为空,请选择有效的股票。');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 设置 WebView HTML 内容
|
||||||
|
// const htmlContent = this.generateWebviewContent(stockCode);
|
||||||
|
// this.webview.setHtml(htmlContent);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 生成 WebView 的 HTML 内容。
|
||||||
|
// */
|
||||||
|
// // private generateWebviewContent(stockCode: string): string {
|
||||||
|
// // return `
|
||||||
|
// // <!DOCTYPE html>
|
||||||
|
// // <html lang="en">
|
||||||
|
// // <head>
|
||||||
|
// // <meta charset="UTF-8">
|
||||||
|
// // <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
// // <title>股票详情</title>
|
||||||
|
// // <style>
|
||||||
|
// // body {
|
||||||
|
// // font-family: Arial, sans-serif;
|
||||||
|
// // margin: 0;
|
||||||
|
// // padding: 20px;
|
||||||
|
// // background: #f5f5f5;
|
||||||
|
// // color: #333;
|
||||||
|
// // }
|
||||||
|
// // h1 {
|
||||||
|
// // font-size: 24px;
|
||||||
|
// // margin-bottom: 10px;
|
||||||
|
// // }
|
||||||
|
// // .info {
|
||||||
|
// // margin: 5px 0;
|
||||||
|
// // }
|
||||||
|
// // </style>
|
||||||
|
// // </head>
|
||||||
|
// // <body>
|
||||||
|
// // <h1>股票详情</h1>
|
||||||
|
// // <div class="info">代码: ${stockCode}</div>
|
||||||
|
// // <div class="info">价格: ¥123.45</div>
|
||||||
|
// // <div class="info">涨跌幅: +3.21%</div>
|
||||||
|
// // </body>
|
||||||
|
// // </html>
|
||||||
|
// // `;
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// private generateWebviewContent(stockCode: string): string {
|
||||||
|
// return `
|
||||||
|
// <!DOCTYPE html>
|
||||||
|
// <html lang="en">
|
||||||
|
// <head>
|
||||||
|
// <meta charset="UTF-8">
|
||||||
|
// <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
// <title>股票详情</title>
|
||||||
|
// <style>
|
||||||
|
// body {
|
||||||
|
// font-family: Arial, sans-serif;
|
||||||
|
// margin: 0;
|
||||||
|
// padding: 20px;
|
||||||
|
// background: #f5f5f5;
|
||||||
|
// color: #333;
|
||||||
|
// }
|
||||||
|
// h1 {
|
||||||
|
// font-size: 24px;
|
||||||
|
// margin-bottom: 10px;
|
||||||
|
// }
|
||||||
|
// .info {
|
||||||
|
// margin: 5px 0;
|
||||||
|
// }
|
||||||
|
// </style>
|
||||||
|
// </head>
|
||||||
|
// <body>
|
||||||
|
// <h1>股票详情</h1>
|
||||||
|
// <div class="info">代码: ${stockCode}</div>
|
||||||
|
// <div id="price" class="info">价格: ¥加载中...</div>
|
||||||
|
// <div id="change" class="info">涨跌幅: 加载中...</div>
|
||||||
|
|
||||||
|
// <script>
|
||||||
|
// // 模拟异步获取股票数据
|
||||||
|
// setTimeout(() => {
|
||||||
|
// document.getElementById('price').textContent = '价格: ¥' + (Math.random() * 100).toFixed(2);
|
||||||
|
// document.getElementById('change').textContent = '涨跌幅: ' + (Math.random() * 10 - 5).toFixed(2) + '%';
|
||||||
|
// }, 1000);
|
||||||
|
// </script>
|
||||||
|
// </body>
|
||||||
|
// </html>
|
||||||
|
// `;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 渲染错误消息。
|
||||||
|
// */
|
||||||
|
// private renderErrorMessage(message: string): void {
|
||||||
|
// if (this.webview) {
|
||||||
|
// const errorContent = `
|
||||||
|
// <!DOCTYPE html>
|
||||||
|
// <html lang="en">
|
||||||
|
// <head>
|
||||||
|
// <meta charset="UTF-8">
|
||||||
|
// <title>错误</title>
|
||||||
|
// </head>
|
||||||
|
// <body>
|
||||||
|
// <h1 style="color: red;">错误</h1>
|
||||||
|
// <p>${message}</p>
|
||||||
|
// </body>
|
||||||
|
// </html>
|
||||||
|
// `;
|
||||||
|
// this.webview.setHtml(errorContent);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 布局调整。
|
||||||
|
// */
|
||||||
|
// override layout(dimension: Dimension): void {
|
||||||
|
// if (this.webview && this.webview.container) {
|
||||||
|
// const webviewContainer = this.webview.container;
|
||||||
|
|
||||||
|
// // 设置 WebView 的宽高
|
||||||
|
// webviewContainer.style.width = `${dimension.width}px`;
|
||||||
|
// webviewContainer.style.height = `${dimension.height}px`;
|
||||||
|
|
||||||
|
// // 限制 WebView 到当前编辑器区域
|
||||||
|
// const clippingContainer = this.getContainer();
|
||||||
|
// if (clippingContainer) {
|
||||||
|
// this.webview.layoutWebviewOverElement(clippingContainer, dimension);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 清空输入内容。
|
||||||
|
// */
|
||||||
|
// override clearInput(): void {
|
||||||
|
// if (this.webview) {
|
||||||
|
// this.webview.setHtml('<!DOCTYPE html><html><body></body></html>'); // 清空内容
|
||||||
|
// }
|
||||||
|
// super.clearInput();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
import { EditorPane } from '../../../../browser/parts/editor/editorPane.js';
|
import { EditorPane } from '../../../../browser/parts/editor/editorPane.js';
|
||||||
import { Dimension } from '../../../../../base/browser/dom.js';
|
import { Dimension } from '../../../../../base/browser/dom.js';
|
||||||
import { StockDetailsInput } from './StockDetailsInput.js';
|
import { StockDetailsInput } from './StockDetailsInput.js';
|
||||||
|
import { IWebviewService, IOverlayWebview } from '../../../../contrib/webview/browser/webview.js';
|
||||||
import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';
|
import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js';
|
||||||
import { IThemeService } from '../../../../../platform/theme/common/themeService.js';
|
import { IThemeService } from '../../../../../platform/theme/common/themeService.js';
|
||||||
import { IStorageService } from '../../../../../platform/storage/common/storage.js';
|
import { IStorageService } from '../../../../../platform/storage/common/storage.js';
|
||||||
|
|
||||||
import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
import { CancellationToken } from '../../../../../base/common/cancellation.js';
|
||||||
import { IEditorOptions } from '../../../../../platform/editor/common/editor.js';
|
import { IEditorOptions } from '../../../../../platform/editor/common/editor.js';
|
||||||
import { IEditorOpenContext } from '../../../../common/editor.js';
|
import { IEditorOpenContext } from '../../../../common/editor.js';
|
||||||
import { IEditorGroup } from '../../../../services/editor/common/editorGroupsService.js';
|
import { IEditorGroup } from '../../../../services/editor/common/editorGroupsService.js';
|
||||||
|
import * as DOM from '../../../../../base/browser/dom.js';
|
||||||
|
|
||||||
|
import { FileAccess } from '../../../../../base/common/network.js';
|
||||||
|
|
||||||
|
|
||||||
export class StockDetailsEditor extends EditorPane {
|
export class StockDetailsEditor extends EditorPane {
|
||||||
static readonly ID = 'workbench.editor.stockDetails';
|
static readonly ID = 'workbench.editor.stockDetails';
|
||||||
|
|
||||||
private container: HTMLElement | null = null;
|
private webview: IOverlayWebview | null = null;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
group: IEditorGroup,
|
group: IEditorGroup,
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@IThemeService themeService: IThemeService,
|
@IThemeService themeService: IThemeService,
|
||||||
@IStorageService storageService: IStorageService
|
@IStorageService storageService: IStorageService,
|
||||||
|
@IWebviewService private readonly webviewService: IWebviewService
|
||||||
) {
|
) {
|
||||||
super(StockDetailsEditor.ID, group, telemetryService, themeService, storageService);
|
super(StockDetailsEditor.ID, group, telemetryService, themeService, storageService);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建编辑器容器并初始化界面。
|
* 创建编辑器容器并初始化 WebView。
|
||||||
*/
|
*/
|
||||||
protected createEditor(parent: HTMLElement): void {
|
protected createEditor(parent: HTMLElement): void {
|
||||||
this.container = document.createElement('div');
|
// 使用 WebView 服务创建 IOverlayWebview 实例
|
||||||
this.container.className = 'stock-details-editor';
|
this.webview = this.webviewService.createWebviewOverlay({
|
||||||
|
providedViewType: 'stockDetailsEditor',
|
||||||
|
title: '股票详情',
|
||||||
|
options: { retainContextWhenHidden: true },
|
||||||
|
contentOptions: {
|
||||||
|
allowScripts: true,
|
||||||
|
localResourceRoots: [
|
||||||
|
FileAccess.asFileUri('vs/workbench/contrib/example/browser/resources')
|
||||||
|
], // 指定资源路径
|
||||||
|
},
|
||||||
|
extension: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
// 添加占位符
|
// 将 WebView 定位到父元素
|
||||||
const placeholder = document.createElement('div');
|
if (this.webview) {
|
||||||
placeholder.className = 'stock-placeholder';
|
const targetWindow = DOM.getActiveWindow();
|
||||||
placeholder.textContent = '请选择一只股票查看详情';
|
if (!targetWindow) {
|
||||||
this.container.appendChild(placeholder);
|
console.error('无法获取活动窗口');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
parent.appendChild(this.container);
|
this.webview.claim(this, targetWindow as any, undefined);
|
||||||
|
this.webview.layoutWebviewOverElement(parent, new Dimension(parent.offsetWidth, parent.offsetHeight));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置编辑器输入。
|
* 设置编辑器输入并更新 WebView 内容。
|
||||||
*/
|
*/
|
||||||
override async setInput(
|
override async setInput(
|
||||||
input: StockDetailsInput,
|
input: StockDetailsInput,
|
||||||
@ -55,85 +296,82 @@ export class StockDetailsEditor extends EditorPane {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await super.setInput(input, options, context, token);
|
await super.setInput(input, options, context, token);
|
||||||
|
|
||||||
if (input.resource) {
|
if (this.webview && input.resource) {
|
||||||
console.log(`setInput 接收到股票代码: ${input.getCode()}`);
|
|
||||||
const stockCode = input.getCode();
|
const stockCode = input.getCode();
|
||||||
|
|
||||||
if (!stockCode || stockCode.trim() === '') {
|
if (!stockCode || stockCode.trim() === '') {
|
||||||
this.renderErrorMessage('股票代码为空,请选择有效的股票。');
|
this.renderErrorMessage('股票代码为空,请选择有效的股票。');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.renderStockDetails(stockCode);
|
// 获取 HTML、CSS 和 JS 文件的路径
|
||||||
} else {
|
const htmlPath = FileAccess.asBrowserUri('vs/workbench/contrib/example/browser/resources/index.html').toString();
|
||||||
this.renderErrorMessage('未提供有效的股票代码');
|
const cssPath = FileAccess.asBrowserUri('vs/workbench/contrib/example/browser/resources/styles.css').toString();
|
||||||
}
|
const jsPath = FileAccess.asBrowserUri('vs/workbench/contrib/example/browser/resources/app.js').toString();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 使用 fetch 动态加载 HTML 文件内容
|
||||||
|
let htmlContent = await fetch(htmlPath)
|
||||||
|
.then(response => response.text())
|
||||||
|
.catch(err => {
|
||||||
|
console.error('加载 HTML 文件失败:', err);
|
||||||
|
return `<h1 style="color: red;">加载 HTML 文件失败: ${err.message}</h1>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 替换 HTML 文件中的动态占位符
|
||||||
|
htmlContent = htmlContent
|
||||||
|
.replace('[[STOCK_CODE]]', stockCode) // 替换股票代码占位符
|
||||||
|
.replace('[[CSS_PATH]]', cssPath) // 替换 CSS 路径占位符
|
||||||
|
.replace('[[JS_PATH]]', jsPath); // 替换 JS 路径占位符
|
||||||
|
|
||||||
|
// 将动态生成的 HTML 设置为 Webview 内容
|
||||||
|
this.webview.setHtml(htmlContent);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载资源失败:', error);
|
||||||
|
this.renderErrorMessage(`加载资源失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据股票代码加载详情。
|
|
||||||
*/
|
|
||||||
private renderStockDetails(stockCode: string): void {
|
|
||||||
if (!this.container) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清空容器内容
|
|
||||||
this.container.textContent = ''; // 不使用 innerHTML
|
|
||||||
|
|
||||||
// 创建标题
|
|
||||||
const title = document.createElement('h3');
|
|
||||||
title.textContent = '股票详情';
|
|
||||||
// 使用内联样式修改标题样式
|
|
||||||
title.style.fontSize = '24px'; // 修改字体大小为 24 像素
|
|
||||||
title.style.fontWeight = 'bold'; // 设置字体加粗
|
|
||||||
title.style.margin = '10px 0'; // 设置上下外边距
|
|
||||||
|
|
||||||
// 创建股票代码段
|
|
||||||
const codeInfo = document.createElement('p');
|
|
||||||
codeInfo.textContent = `代码: ${stockCode}`;
|
|
||||||
|
|
||||||
// 模拟价格信息
|
|
||||||
const priceInfo = document.createElement('p');
|
|
||||||
priceInfo.textContent = '价格: ¥123.45';
|
|
||||||
|
|
||||||
// 模拟涨跌幅信息
|
|
||||||
const changeInfo = document.createElement('p');
|
|
||||||
changeInfo.textContent = '涨跌幅: +3.21%';
|
|
||||||
|
|
||||||
// 添加到容器
|
|
||||||
this.container.appendChild(title);
|
|
||||||
this.container.appendChild(codeInfo);
|
|
||||||
this.container.appendChild(priceInfo);
|
|
||||||
this.container.appendChild(changeInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染错误消息。
|
* 渲染错误消息。
|
||||||
*/
|
*/
|
||||||
private renderErrorMessage(message: string): void {
|
private renderErrorMessage(message: string): void {
|
||||||
if (!this.container) {
|
if (this.webview) {
|
||||||
return;
|
const errorContent = `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>错误</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="color: red;">错误</h1>
|
||||||
|
<p>${message}</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
this.webview.setHtml(errorContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.container.textContent = ''; // 清空之前的内容
|
|
||||||
|
|
||||||
const errorDiv = document.createElement('div');
|
|
||||||
errorDiv.className = 'stock-error';
|
|
||||||
errorDiv.textContent = message;
|
|
||||||
|
|
||||||
this.container.appendChild(errorDiv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 布局调整。
|
* 布局调整。
|
||||||
*/
|
*/
|
||||||
override layout(dimension: Dimension): void {
|
override layout(dimension: Dimension): void {
|
||||||
if (this.container) {
|
if (this.webview && this.webview.container) {
|
||||||
this.container.style.width = `${dimension.width}px`;
|
const webviewContainer = this.webview.container;
|
||||||
this.container.style.height = `${dimension.height}px`;
|
webviewContainer.style.width = `${dimension.width}px`;
|
||||||
|
webviewContainer.style.height = `${dimension.height}px`;
|
||||||
|
|
||||||
|
const clippingContainer = this.getContainer();
|
||||||
|
if (clippingContainer) {
|
||||||
|
this.webview.layoutWebviewOverElement(clippingContainer, dimension);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +379,12 @@ export class StockDetailsEditor extends EditorPane {
|
|||||||
* 清空输入内容。
|
* 清空输入内容。
|
||||||
*/
|
*/
|
||||||
override clearInput(): void {
|
override clearInput(): void {
|
||||||
if (this.container) {
|
if (this.webview) {
|
||||||
this.container.textContent = ''; // 不使用 innerHTML
|
this.webview.setHtml('<!DOCTYPE html><html><body></body></html>'); // 清空内容
|
||||||
}
|
}
|
||||||
super.clearInput();
|
super.clearInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/edit
|
|||||||
import { EditorExtensions } from '../../../common/editor.js';
|
import { EditorExtensions } from '../../../common/editor.js';
|
||||||
import { StockDetailsEditor } from './editors/StockDetailsEditor.js';
|
import { StockDetailsEditor } from './editors/StockDetailsEditor.js';
|
||||||
import { StockDetailsInput } from './editors/StockDetailsInput.js';
|
import { StockDetailsInput } from './editors/StockDetailsInput.js';
|
||||||
import { IStockDetailsService, StockDetailsService } from './common/stockDetailsService.js';
|
import { IStockDetailsService, StockDetailsService } from '../common/stockDetailsService.js';
|
||||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||||
|
|
||||||
// 注册消息传递服务
|
// 注册消息传递服务
|
||||||
|
13
src/vs/workbench/contrib/example/browser/resources/app.js
Normal file
13
src/vs/workbench/contrib/example/browser/resources/app.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// 模拟异步获取股票数据
|
||||||
|
setTimeout(() => {
|
||||||
|
const stockCode = '000001'; // 示例代码,实际可通过外部注入
|
||||||
|
document.getElementById('stock-code').textContent = stockCode;
|
||||||
|
document.getElementById('price').textContent = '价格: ¥' + (Math.random() * 100).toFixed(2);
|
||||||
|
document.getElementById('change').textContent = '涨跌幅: ' + (Math.random() * 10 - 5).toFixed(2) + '%';
|
||||||
|
}, 1000);
|
||||||
|
});
|
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>股票详情</title>
|
||||||
|
<link rel="stylesheet" href="[[CSS_PATH]]"> <!-- 动态替换 CSS 路径 -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>股票详情</h1>
|
||||||
|
<div class="info">代码: <span id="stock-code">[[STOCK_CODE]]</span></div> <!-- 动态替换股票代码 -->
|
||||||
|
<div id="price" class="info">价格: ¥加载中...</div>
|
||||||
|
<div id="change" class="info">涨跌幅: 加载中...</div>
|
||||||
|
<script src="[[JS_PATH]]"></script> <!-- 动态替换 JS 路径 -->
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,16 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
@ -18,7 +18,7 @@ import { IAccessibleViewService } from '../../../../../platform/accessibility/br
|
|||||||
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
||||||
import * as DOM from '../../../../../base/browser/dom.js';
|
import * as DOM from '../../../../../base/browser/dom.js';
|
||||||
|
|
||||||
import { IStockDetailsService, StockDetail } from '../common/stockDetailsService.js';
|
import { IStockDetailsService, StockDetail } from '../../common/stockDetailsService.js';
|
||||||
|
|
||||||
export class AuxiliaryView extends ViewPane {
|
export class AuxiliaryView extends ViewPane {
|
||||||
private stockDetailContainer: HTMLElement | undefined;
|
private stockDetailContainer: HTMLElement | undefined;
|
||||||
|
@ -23,8 +23,8 @@ import './media/exampleViewContainer.css';
|
|||||||
import { IEditorService } from '../../../../services/editor/common/editorService.js';
|
import { IEditorService } from '../../../../services/editor/common/editorService.js';
|
||||||
import { StockDetailsInput } from '../editors/StockDetailsInput.js';
|
import { StockDetailsInput } from '../editors/StockDetailsInput.js';
|
||||||
import { IWorkbenchLayoutService, Parts } from '../../../../services/layout/browser/layoutService.js';
|
import { IWorkbenchLayoutService, Parts } from '../../../../services/layout/browser/layoutService.js';
|
||||||
import { IStockDetailsService, StockDetail } from '../common/stockDetailsService.js';
|
import { IStockDetailsService, StockDetail } from '../../common/stockDetailsService.js';
|
||||||
|
import { httpService } from '../../common/stockHttpService.js';
|
||||||
|
|
||||||
export class ExampleView extends ViewPane {
|
export class ExampleView extends ViewPane {
|
||||||
constructor(
|
constructor(
|
||||||
@ -62,30 +62,77 @@ export class ExampleView extends ViewPane {
|
|||||||
this.editorService.onDidActiveEditorChange(() => this.onActiveEditorChange());
|
this.editorService.onDidActiveEditorChange(() => this.onActiveEditorChange());
|
||||||
}
|
}
|
||||||
|
|
||||||
override renderBody(container: HTMLElement): void {
|
// override renderBody(container: HTMLElement): void {
|
||||||
|
// super.renderBody(container);
|
||||||
|
|
||||||
|
// const ul = DOM.$('ul'); // 创建一个无序列表
|
||||||
|
// ul.classList.add('stock-list'); // 为列表添加样式类
|
||||||
|
// const data = [
|
||||||
|
// { name: 'Stock A', code: '000001', price: 100 },
|
||||||
|
// { name: 'Stock B', code: '000002', price: 200 },
|
||||||
|
// { name: 'Stock C', code: '000003', price: 300 },
|
||||||
|
// { name: 'Stock D', code: '000004', price: 400 },
|
||||||
|
// { name: 'Stock E', code: '000005', price: 500 },
|
||||||
|
// ]; // 假数据
|
||||||
|
|
||||||
|
// for (const stock of data) {
|
||||||
|
// const li = DOM.$('li');
|
||||||
|
// li.textContent = `${stock.name} (${stock.code}) ¥${stock.price.toFixed(2)}`;
|
||||||
|
// li.classList.add('stock-item');
|
||||||
|
// li.addEventListener('click', () => {
|
||||||
|
// this.openStockDetails(stock); // 点击时打开股票详情
|
||||||
|
// });
|
||||||
|
// ul.appendChild(li);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// container.appendChild(ul); // 将列表附加到容器中
|
||||||
|
// }
|
||||||
|
|
||||||
|
override async renderBody(container: HTMLElement): Promise<void> {
|
||||||
super.renderBody(container);
|
super.renderBody(container);
|
||||||
|
|
||||||
const ul = DOM.$('ul'); // 创建一个无序列表
|
// 保持现有的静态数据和渲染逻辑
|
||||||
ul.classList.add('stock-list'); // 为列表添加样式类
|
const ul = DOM.$('ul');
|
||||||
|
ul.classList.add('stock-list');
|
||||||
|
|
||||||
const data = [
|
const data = [
|
||||||
{ name: 'Stock A', code: '000001', price: 100 },
|
{ name: 'Stock A', code: '000001', price: 100 },
|
||||||
{ name: 'Stock B', code: '000002', price: 200 },
|
{ name: 'Stock B', code: '000002', price: 200 },
|
||||||
{ name: 'Stock C', code: '000003', price: 300 },
|
{ name: 'Stock C', code: '000003', price: 300 },
|
||||||
{ name: 'Stock D', code: '000004', price: 400 },
|
{ name: 'Stock D', code: '000004', price: 400 },
|
||||||
{ name: 'Stock E', code: '000005', price: 500 },
|
{ name: 'Stock E', code: '000005', price: 500 },
|
||||||
]; // 假数据
|
];
|
||||||
|
|
||||||
for (const stock of data) {
|
for (const stock of data) {
|
||||||
const li = DOM.$('li');
|
const li = DOM.$('li');
|
||||||
li.textContent = `${stock.name} (${stock.code}) ¥${stock.price.toFixed(2)}`;
|
li.textContent = `${stock.name} (${stock.code}) ¥${stock.price.toFixed(2)}`;
|
||||||
li.classList.add('stock-item');
|
li.classList.add('stock-item');
|
||||||
li.addEventListener('click', () => {
|
li.addEventListener('click', () => {
|
||||||
this.openStockDetails(stock); // 点击时打开股票详情
|
this.openStockDetails(stock);
|
||||||
});
|
});
|
||||||
ul.appendChild(li);
|
ul.appendChild(li);
|
||||||
}
|
}
|
||||||
|
|
||||||
container.appendChild(ul); // 将列表附加到容器中
|
container.appendChild(ul);
|
||||||
|
|
||||||
|
// 发起 POST 请求
|
||||||
|
const requestBody = {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
year: '1',
|
||||||
|
indexType: 'hs300'
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('即将进入请求调用');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await httpService.fetchPostJson('https://www.shidaotec.com/api/strategy/selectStockPageList', requestBody);
|
||||||
|
console.log('API Response:', response); // 请求完成后再打印
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error fetching stock data:', err); // 捕获异常
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('已步过');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import { IAccessibleViewService } from '../../../../../platform/accessibility/br
|
|||||||
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
||||||
import * as DOM from '../../../../../base/browser/dom.js';
|
import * as DOM from '../../../../../base/browser/dom.js';
|
||||||
|
|
||||||
import { IStockDetailsService, StockDetail } from '../common/stockDetailsService.js';
|
import { IStockDetailsService, StockDetail } from '../../common/stockDetailsService.js';
|
||||||
|
|
||||||
export class PanelView extends ViewPane {
|
export class PanelView extends ViewPane {
|
||||||
private stockDetailContainer: HTMLElement | undefined;
|
private stockDetailContainer: HTMLElement | undefined;
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { createDecorator } from '../../../../../platform/instantiation/common/instantiation.js';
|
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
|
||||||
import { Emitter, Event } from '../../../../../base/common/event.js';
|
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定义服务接口和标识符
|
* 定义服务接口和标识符
|
38
src/vs/workbench/contrib/example/common/stockHttpService.ts
Normal file
38
src/vs/workbench/contrib/example/common/stockHttpService.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
export class HttpService {
|
||||||
|
async fetchJson(url: string, options: RequestInit = {}): Promise<any> {
|
||||||
|
const response = await fetch(url, options);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status} - ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchText(url: string, options: RequestInit = {}): Promise<string> {
|
||||||
|
const response = await fetch(url, options);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status} - ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchPostJson(url: string, body: any, headers: Record<string, string> = { 'Content-Type': 'application/json' }): Promise<any> {
|
||||||
|
console.log('Fetching data with body:', body);
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
// console.log('Response:', response);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP Error: ${response.status} - ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出单例
|
||||||
|
export const httpService = new HttpService();
|
Loading…
Reference in New Issue
Block a user