Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit781feb2

Browse files
Vigilansjdneo
authored andcommitted
Extract leetcode webview base class & add md settings listener (LeetCode-OpenSource#270)
1 parentecac298 commit781feb2

9 files changed

+226
-192
lines changed

‎src/commands/submit.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { leetCodeExecutor } from "../leetCodeExecutor";
66
import{leetCodeManager}from"../leetCodeManager";
77
import{DialogType,promptForOpenOutputChannel,promptForSignIn}from"../utils/uiUtils";
88
import{getActiveFilePath}from"../utils/workspaceUtils";
9-
import{leetCodeResultProvider}from"../webview/leetCodeResultProvider";
9+
import{leetCodeSubmissionProvider}from"../webview/leetCodeSubmissionProvider";
1010

1111
exportasyncfunctionsubmitSolution(uri?:vscode.Uri):Promise<void>{
1212
if(!leetCodeManager.getUser()){
@@ -21,7 +21,7 @@ export async function submitSolution(uri?: vscode.Uri): Promise<void> {
2121

2222
try{
2323
constresult:string=awaitleetCodeExecutor.submitSolution(filePath);
24-
awaitleetCodeResultProvider.show(result);
24+
awaitleetCodeSubmissionProvider.show(result);
2525
}catch(error){
2626
awaitpromptForOpenOutputChannel("Failed to submit the solution. Please open the output channel for details.",DialogType.error);
2727
}

‎src/commands/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { isWindows, usingCmd } from "../utils/osUtils";
1010
import{DialogType,promptForOpenOutputChannel,showFileSelectDialog}from"../utils/uiUtils";
1111
import{getActiveFilePath}from"../utils/workspaceUtils";
1212
import*aswslfrom"../utils/wslUtils";
13-
import{leetCodeResultProvider}from"../webview/leetCodeResultProvider";
13+
import{leetCodeSubmissionProvider}from"../webview/leetCodeSubmissionProvider";
1414

1515
exportasyncfunctiontestSolution(uri?:vscode.Uri):Promise<void>{
1616
try{
@@ -81,7 +81,7 @@ export async function testSolution(uri?: vscode.Uri): Promise<void> {
8181
if(!result){
8282
return;
8383
}
84-
awaitleetCodeResultProvider.show(result);
84+
awaitleetCodeSubmissionProvider.show(result);
8585
}catch(error){
8686
awaitpromptForOpenOutputChannel("Failed to test the solution. Please open the output channel for details.",DialogType.error);
8787
}

‎src/extension.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import { leetCodeManager } from "./leetCodeManager";
1818
import{leetCodeStatusBarController}from"./statusbar/leetCodeStatusBarController";
1919
import{DialogType,promptForOpenOutputChannel}from"./utils/uiUtils";
2020
import{leetCodePreviewProvider}from"./webview/leetCodePreviewProvider";
21-
import{leetCodeResultProvider}from"./webview/leetCodeResultProvider";
2221
import{leetCodeSolutionProvider}from"./webview/leetCodeSolutionProvider";
22+
import{leetCodeSubmissionProvider}from"./webview/leetCodeSubmissionProvider";
23+
import{markdownEngine}from"./webview/markdownEngine";
2324

2425
exportasyncfunctionactivate(context:vscode.ExtensionContext):Promise<void>{
2526
try{
@@ -33,17 +34,15 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
3334
});
3435

3536
constleetCodeTreeDataProvider:LeetCodeTreeDataProvider=newLeetCodeTreeDataProvider(context);
36-
leetCodePreviewProvider.initialize(context);
37-
leetCodeResultProvider.initialize(context);
38-
leetCodeSolutionProvider.initialize(context);
3937

4038
context.subscriptions.push(
4139
leetCodeStatusBarController,
4240
leetCodeChannel,
4341
leetCodePreviewProvider,
44-
leetCodeResultProvider,
42+
leetCodeSubmissionProvider,
4543
leetCodeSolutionProvider,
4644
leetCodeExecutor,
45+
markdownEngine,
4746
vscode.window.createTreeView("leetCodeExplorer",{treeDataProvider:leetCodeTreeDataProvider,showCollapseAll:true}),
4847
vscode.languages.registerCodeLensProvider({scheme:"file"},codeLensProvider),
4948
vscode.commands.registerCommand("leetcode.deleteCache",()=>cache.deleteCache()),

‎src/webview/LeetCodeWebview.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) jdneo. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import{ConfigurationChangeEvent,Disposable,ViewColumn,WebviewPanel,window,workspace}from"vscode";
5+
import{markdownEngine}from"./markdownEngine";
6+
7+
exportabstractclassLeetCodeWebviewimplementsDisposable{
8+
9+
protectedpanel:WebviewPanel|undefined;
10+
privatelisteners:Disposable[]=[];
11+
12+
publicdispose():void{
13+
if(this.panel){
14+
this.panel.dispose();
15+
}
16+
}
17+
18+
protectedshowWebviewInternal():void{
19+
const{ viewType, title, viewColumn, preserveFocus}=this.getWebviewOption();
20+
if(!this.panel){
21+
this.panel=window.createWebviewPanel(viewType,title,{ viewColumn, preserveFocus},{
22+
enableScripts:true,
23+
enableCommandUris:true,
24+
enableFindWidget:true,
25+
retainContextWhenHidden:true,
26+
localResourceRoots:markdownEngine.localResourceRoots,
27+
});
28+
this.panel.onDidDispose(this.onDidDisposeWebview,this,this.listeners);
29+
this.panel.webview.onDidReceiveMessage(this.onDidReceiveMessage,this,this.listeners);
30+
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration,this,this.listeners);
31+
}else{
32+
this.panel.title=title;
33+
this.panel.reveal(viewColumn,preserveFocus);
34+
}
35+
this.panel.webview.html=this.getWebviewContent();
36+
}
37+
38+
protectedonDidDisposeWebview():void{
39+
this.panel=undefined;
40+
for(constlistenerofthis.listeners){
41+
listener.dispose();
42+
}
43+
this.listeners=[];
44+
}
45+
46+
protectedasynconDidChangeConfiguration(event:ConfigurationChangeEvent):Promise<void>{
47+
if(this.panel&&event.affectsConfiguration("markdown")){
48+
this.panel.webview.html=this.getWebviewContent();
49+
}
50+
}
51+
52+
protectedasynconDidReceiveMessage(_message:any):Promise<void>{/* no special rule */}
53+
54+
protectedabstractgetWebviewOption():ILeetCodeWebviewOption;
55+
56+
protectedabstractgetWebviewContent():string;
57+
}
58+
59+
exportinterfaceILeetCodeWebviewOption{
60+
viewType:string;
61+
title:string;
62+
viewColumn:ViewColumn;
63+
preserveFocus?:boolean;
64+
}

‎src/webview/leetCodePreviewProvider.ts

Lines changed: 69 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,39 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import{commands,Disposable,ExtensionContext,ViewColumn,WebviewPanel,window}from"vscode";
4+
import{commands,ViewColumn}from"vscode";
55
import{leetCodeExecutor}from"../leetCodeExecutor";
66
import{IProblem}from"../shared";
7+
import{ILeetCodeWebviewOption,LeetCodeWebview}from"./LeetCodeWebview";
78
import{markdownEngine}from"./markdownEngine";
89

9-
classLeetCodePreviewProviderimplementsDisposable{
10+
classLeetCodePreviewProviderextendsLeetCodeWebview{
1011

11-
privatecontext:ExtensionContext;
1212
privatenode:IProblem;
13-
privatepanel:WebviewPanel|undefined;
14-
15-
publicinitialize(context:ExtensionContext):void{
16-
this.context=context;
17-
}
13+
privatedescription:IDescription;
1814

1915
publicasyncshow(node:IProblem):Promise<void>{
20-
// Fetch problem first before creating webview panel
21-
constdescString:string=awaitleetCodeExecutor.getDescription(node);
22-
16+
this.description=this.parseDescription(awaitleetCodeExecutor.getDescription(node),node);
2317
this.node=node;
24-
if(!this.panel){
25-
this.panel=window.createWebviewPanel("leetcode.preview","Preview Problem",ViewColumn.One,{
26-
enableScripts:true,
27-
enableCommandUris:true,
28-
enableFindWidget:true,
29-
retainContextWhenHidden:true,
30-
localResourceRoots:markdownEngine.localResourceRoots,
31-
});
32-
33-
this.panel.webview.onDidReceiveMessage(async(message:IWebViewMessage)=>{
34-
switch(message.command){
35-
case"ShowProblem":{
36-
awaitcommands.executeCommand("leetcode.showProblem",this.node);
37-
break;
38-
}
39-
}
40-
},this,this.context.subscriptions);
41-
42-
this.panel.onDidDispose(()=>{
43-
this.panel=undefined;
44-
},null,this.context.subscriptions);
45-
}
46-
47-
constdescription:IDescription=this.parseDescription(descString,node);
48-
this.panel.webview.html=this.getWebViewContent(description);
49-
this.panel.title=`${node.name}: Preview`;
50-
this.panel.reveal(ViewColumn.One);
18+
this.showWebviewInternal();
5119
}
5220

53-
publicdispose():void{
54-
if(this.panel){
55-
this.panel.dispose();
56-
}
57-
}
58-
59-
privateparseDescription(descString:string,problem:IProblem):IDescription{
60-
const[
61-
/* title */,,
62-
url,,
63-
/* tags */,,
64-
/* langs */,,
65-
category,
66-
difficulty,
67-
likes,
68-
dislikes,
69-
/* accepted */,
70-
/* submissions */,
71-
/* testcase */,,
72-
...body
73-
]=descString.split("\n");
21+
protectedgetWebviewOption():ILeetCodeWebviewOption{
7422
return{
75-
title:problem.name,
76-
url,
77-
tags:problem.tags,
78-
companies:problem.companies,
79-
category:category.slice(2),
80-
difficulty:difficulty.slice(2),
81-
likes:likes.split(": ")[1].trim(),
82-
dislikes:dislikes.split(": ")[1].trim(),
83-
body:body.join("\n").replace(/<pre>\s*([^]+?)\s*<\/pre>/g,"<pre><code>$1</code></pre>"),
23+
viewType:"leetcode.preview",
24+
title:`${this.node.name}: Preview`,
25+
viewColumn:ViewColumn.One,
8426
};
8527
}
8628

87-
privategetWebViewContent(desc:IDescription):string{
88-
constmdStyles:string=markdownEngine.getStyles();
89-
constbuttonStyle:string=`
90-
<style>
29+
protectedgetWebviewContent():string{
30+
constbutton:{element:string,script:string,style:string}={
31+
element:`<button id="solve">Code Now</button>`,
32+
script:`const button = document.getElementById('solve');
33+
button.onclick = () => vscode.postMessage({
34+
command: 'ShowProblem',
35+
});`,
36+
style:`<style>
9137
#solve {
9238
position: fixed;
9339
bottom: 1rem;
@@ -104,9 +50,9 @@ class LeetCodePreviewProvider implements Disposable {
10450
#solve:active {
10551
border: 0;
10652
}
107-
</style>
108-
`;
109-
const{ title, url, category, difficulty, likes, dislikes, body}=desc;
53+
</style>`,
54+
};
55+
const{ title, url, category, difficulty, likes, dislikes, body}=this.description;
11056
consthead:string=markdownEngine.render(`# [${title}](${url})`);
11157
constinfo:string=markdownEngine.render([
11258
`| Category | Difficulty | Likes | Dislikes |`,
@@ -117,7 +63,7 @@ class LeetCodePreviewProvider implements Disposable {
11763
`<details>`,
11864
`<summary><strong>Tags</strong></summary>`,
11965
markdownEngine.render(
120-
desc.tags
66+
this.description.tags
12167
.map((t:string)=>`[\`${t}\`](https://leetcode.com/tag/${t})`)
12268
.join(" | "),
12369
),
@@ -127,7 +73,7 @@ class LeetCodePreviewProvider implements Disposable {
12773
`<details>`,
12874
`<summary><strong>Companies</strong></summary>`,
12975
markdownEngine.render(
130-
desc.companies
76+
this.description.companies
13177
.map((c:string)=>`\`${c}\``)
13278
.join(" | "),
13379
),
@@ -137,28 +83,67 @@ class LeetCodePreviewProvider implements Disposable {
13783
<!DOCTYPE html>
13884
<html>
13985
<head>
140-
${mdStyles}
141-
${buttonStyle}
86+
${markdownEngine.getStyles()}
87+
${button.style}
14288
</head>
14389
<body>
14490
${head}
14591
${info}
14692
${tags}
14793
${companies}
14894
${body}
149-
<button>Code Now</button>
95+
${button.element}
15096
<script>
15197
const vscode = acquireVsCodeApi();
152-
const button = document.getElementById('solve');
153-
button.onclick = () => vscode.postMessage({
154-
command: 'ShowProblem',
155-
});
98+
${button.script}
15699
</script>
157100
</body>
158101
</html>
159102
`;
160103
}
161104

105+
protectedonDidDisposeWebview():void{
106+
super.onDidDisposeWebview();
107+
deletethis.node;
108+
deletethis.description;
109+
}
110+
111+
protectedasynconDidReceiveMessage(message:IWebViewMessage):Promise<void>{
112+
switch(message.command){
113+
case"ShowProblem":{
114+
awaitcommands.executeCommand("leetcode.showProblem",this.node);
115+
break;
116+
}
117+
}
118+
}
119+
120+
privateparseDescription(descString:string,problem:IProblem):IDescription{
121+
const[
122+
/* title */,,
123+
url,,
124+
/* tags */,,
125+
/* langs */,,
126+
category,
127+
difficulty,
128+
likes,
129+
dislikes,
130+
/* accepted */,
131+
/* submissions */,
132+
/* testcase */,,
133+
...body
134+
]=descString.split("\n");
135+
return{
136+
title:problem.name,
137+
url,
138+
tags:problem.tags,
139+
companies:problem.companies,
140+
category:category.slice(2),
141+
difficulty:difficulty.slice(2),
142+
likes:likes.split(": ")[1].trim(),
143+
dislikes:dislikes.split(": ")[1].trim(),
144+
body:body.join("\n").replace(/<pre>\s*([^]+?)\s*<\/pre>/g,"<pre><code>$1</code></pre>"),
145+
};
146+
}
162147
}
163148

164149
interfaceIDescription{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp