1
1
// Copyright (c) jdneo. All rights reserved.
2
2
// Licensed under the MIT license.
3
3
4
- import { commands , Disposable , ExtensionContext , ViewColumn , WebviewPanel , window } from "vscode" ;
4
+ import { commands , ViewColumn } from "vscode" ;
5
5
import { leetCodeExecutor } from "../leetCodeExecutor" ;
6
6
import { IProblem } from "../shared" ;
7
+ import { ILeetCodeWebviewOption , LeetCodeWebview } from "./LeetCodeWebview" ;
7
8
import { markdownEngine } from "./markdownEngine" ;
8
9
9
- class LeetCodePreviewProvider implements Disposable {
10
+ class LeetCodePreviewProvider extends LeetCodeWebview {
10
11
11
- private context : ExtensionContext ;
12
12
private node : IProblem ;
13
- private panel : WebviewPanel | undefined ;
14
-
15
- public initialize ( context : ExtensionContext ) : void {
16
- this . context = context ;
17
- }
13
+ private description : IDescription ;
18
14
19
15
public async show ( node : IProblem ) : Promise < void > {
20
- // Fetch problem first before creating webview panel
21
- const descString : string = await leetCodeExecutor . getDescription ( node ) ;
22
-
16
+ this . description = this . parseDescription ( await leetCodeExecutor . getDescription ( node ) , node ) ;
23
17
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
- await commands . 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
- const description : 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 ( ) ;
51
19
}
52
20
53
- public dispose ( ) : void {
54
- if ( this . panel ) {
55
- this . panel . dispose ( ) ;
56
- }
57
- }
58
-
59
- private parseDescription ( 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
+ protected getWebviewOption ( ) : ILeetCodeWebviewOption {
74
22
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 ( / < p r e > \s * ( [ ^ ] + ?) \s * < \/ p r e > / g, "<pre><code>$1</code></pre>" ) ,
23
+ viewType : "leetcode.preview" ,
24
+ title : `${ this . node . name } : Preview` ,
25
+ viewColumn : ViewColumn . One ,
84
26
} ;
85
27
}
86
28
87
- private getWebViewContent ( desc : IDescription ) : string {
88
- const mdStyles : string = markdownEngine . getStyles ( ) ;
89
- const buttonStyle : string = `
90
- <style>
29
+ protected getWebviewContent ( ) : string {
30
+ const button : { 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>
91
37
#solve {
92
38
position: fixed;
93
39
bottom: 1rem;
@@ -104,9 +50,9 @@ class LeetCodePreviewProvider implements Disposable {
104
50
#solve:active {
105
51
border: 0;
106
52
}
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 ;
110
56
const head : string = markdownEngine . render ( `# [${ title } ](${ url } )` ) ;
111
57
const info : string = markdownEngine . render ( [
112
58
`| Category | Difficulty | Likes | Dislikes |` ,
@@ -117,7 +63,7 @@ class LeetCodePreviewProvider implements Disposable {
117
63
`<details>` ,
118
64
`<summary><strong>Tags</strong></summary>` ,
119
65
markdownEngine . render (
120
- desc . tags
66
+ this . description . tags
121
67
. map ( ( t : string ) => `[\`${ t } \`](https://leetcode.com/tag/${ t } )` )
122
68
. join ( " | " ) ,
123
69
) ,
@@ -127,7 +73,7 @@ class LeetCodePreviewProvider implements Disposable {
127
73
`<details>` ,
128
74
`<summary><strong>Companies</strong></summary>` ,
129
75
markdownEngine . render (
130
- desc . companies
76
+ this . description . companies
131
77
. map ( ( c : string ) => `\`${ c } \`` )
132
78
. join ( " | " ) ,
133
79
) ,
@@ -137,28 +83,67 @@ class LeetCodePreviewProvider implements Disposable {
137
83
<!DOCTYPE html>
138
84
<html>
139
85
<head>
140
- ${ mdStyles }
141
- ${ buttonStyle }
86
+ ${ markdownEngine . getStyles ( ) }
87
+ ${ button . style }
142
88
</head>
143
89
<body>
144
90
${ head }
145
91
${ info }
146
92
${ tags }
147
93
${ companies }
148
94
${ body }
149
- < button id="solve">Code Now</button>
95
+ ${ button . element }
150
96
<script>
151
97
const vscode = acquireVsCodeApi();
152
- const button = document.getElementById('solve');
153
- button.onclick = () => vscode.postMessage({
154
- command: 'ShowProblem',
155
- });
98
+ ${ button . script }
156
99
</script>
157
100
</body>
158
101
</html>
159
102
` ;
160
103
}
161
104
105
+ protected onDidDisposeWebview ( ) : void {
106
+ super . onDidDisposeWebview ( ) ;
107
+ delete this . node ;
108
+ delete this . description ;
109
+ }
110
+
111
+ protected async onDidReceiveMessage ( message : IWebViewMessage ) : Promise < void > {
112
+ switch ( message . command ) {
113
+ case "ShowProblem" : {
114
+ await commands . executeCommand ( "leetcode.showProblem" , this . node ) ;
115
+ break ;
116
+ }
117
+ }
118
+ }
119
+
120
+ private parseDescription ( 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 ( / < p r e > \s * ( [ ^ ] + ?) \s * < \/ p r e > / g, "<pre><code>$1</code></pre>" ) ,
145
+ } ;
146
+ }
162
147
}
163
148
164
149
interface IDescription {
0 commit comments