@@ -8,51 +8,54 @@ import { ILeetCodeWebviewOption, LeetCodeWebview } from "./LeetCodeWebview";
8
8
import { markdownEngine } from "./markdownEngine" ;
9
9
10
10
class LeetCodePreviewProvider extends LeetCodeWebview {
11
-
12
- protected readonly viewType : string = "leetcode.preview" ;
13
- private node : IProblem ;
14
- private description : IDescription ;
15
- private sideMode : boolean = false ;
16
-
17
- public isSideMode ( ) : boolean {
18
- return this . sideMode ;
19
- }
20
-
21
- public show ( descString : string , node : IProblem , isSideMode : boolean = false ) : void {
22
- this . description = this . parseDescription ( descString , node ) ;
23
- this . node = node ;
24
- this . sideMode = isSideMode ;
25
- this . showWebviewInternal ( ) ;
26
- // Comment out this operation since it sometimes may cause the webview become empty.
27
- // Waiting for the progress of the VS Code side issue: https://github.com/microsoft/vscode/issues/3742
28
- // if (this.sideMode) {
29
- // this.hideSideBar(); // For better view area
30
- // }
31
- }
32
-
33
- protected getWebviewOption ( ) : ILeetCodeWebviewOption {
34
- if ( ! this . sideMode ) {
35
- return {
36
- title : `${ this . node . name } : Preview` ,
37
- viewColumn : ViewColumn . One ,
38
- } ;
39
- } else {
40
- return {
41
- title : "Description" ,
42
- viewColumn : ViewColumn . Two ,
43
- preserveFocus : true ,
44
- } ;
45
- }
11
+ protected readonly viewType : string = "leetcode.preview" ;
12
+ private node : IProblem ;
13
+ private description : IDescription ;
14
+ private sideMode : boolean = false ;
15
+
16
+ public isSideMode ( ) : boolean {
17
+ return this . sideMode ;
18
+ }
19
+
20
+ public show (
21
+ descString : string ,
22
+ node : IProblem ,
23
+ isSideMode : boolean = false
24
+ ) : void {
25
+ this . description = this . parseDescription ( descString , node ) ;
26
+ this . node = node ;
27
+ this . sideMode = isSideMode ;
28
+ this . showWebviewInternal ( ) ;
29
+ // Comment out this operation since it sometimes may cause the webview become empty.
30
+ // Waiting for the progress of the VS Code side issue: https://github.com/microsoft/vscode/issues/3742
31
+ // if (this.sideMode) {
32
+ // this.hideSideBar(); // For better view area
33
+ // }
34
+ }
35
+
36
+ protected getWebviewOption ( ) : ILeetCodeWebviewOption {
37
+ if ( ! this . sideMode ) {
38
+ return {
39
+ title : `${ this . node . name } : Preview` ,
40
+ viewColumn : ViewColumn . One ,
41
+ } ;
42
+ } else {
43
+ return {
44
+ title : "Description" ,
45
+ viewColumn : ViewColumn . Two ,
46
+ preserveFocus : true ,
47
+ } ;
46
48
}
49
+ }
47
50
48
- protected getWebviewContent ( ) : string {
49
- const button : { element : string , script : string , style : string } = {
50
- element : `<button id="solve">Code Now</button>` ,
51
- script : `const button = document.getElementById('solve');
51
+ protected getWebviewContent ( ) : string {
52
+ const button : { element : string ; script : string ; style : string } = {
53
+ element : `<button id="solve">Code Now</button>` ,
54
+ script : `const button = document.getElementById('solve');
52
55
button.onclick = () => vscode.postMessage({
53
56
command: 'ShowProblem',
54
57
});` ,
55
- style : `<style>
58
+ style : `<style>
56
59
#solve {
57
60
position: fixed;
58
61
bottom: 1rem;
@@ -70,36 +73,41 @@ class LeetCodePreviewProvider extends LeetCodeWebview {
70
73
border: 0;
71
74
}
72
75
</style>` ,
73
- } ;
74
- const { title, url, category, difficulty, likes, dislikes, body } = this . description ;
75
- const head : string = markdownEngine . render ( `# [${ title } ](${ url } )` ) ;
76
- const info : string = markdownEngine . render ( [
77
- `| Category | Difficulty | Likes | Dislikes |` ,
78
- `| :------: | :--------: | :---: | :------: |` ,
79
- `| ${ category } | ${ difficulty } | ${ likes } | ${ dislikes } |` ,
80
- ] . join ( "\n" ) ) ;
81
- const tags : string = [
82
- `<details>` ,
83
- `<summary><strong>Tags</strong></summary>` ,
84
- markdownEngine . render (
85
- this . description . tags
86
- . map ( ( t : string ) => `[\`${ t } \`](https://leetcode.com/tag/${ t } )` )
87
- . join ( " | " ) ,
88
- ) ,
89
- `</details>` ,
90
- ] . join ( "\n" ) ;
91
- const companies : string = [
92
- `<details>` ,
93
- `<summary><strong>Companies</strong></summary>` ,
94
- markdownEngine . render (
95
- this . description . companies
96
- . map ( ( c : string ) => `\`${ c } \`` )
97
- . join ( " | " ) ,
98
- ) ,
99
- `</details>` ,
100
- ] . join ( "\n" ) ;
101
- const links : string = markdownEngine . render ( `[Discussion](${ this . getDiscussionLink ( url ) } ) | [Solution](${ this . getSolutionLink ( url ) } )` ) ;
102
- return `
76
+ } ;
77
+ const { title, url, category, difficulty, likes, dislikes, body } =
78
+ this . description ;
79
+ const head : string = markdownEngine . render ( `# [${ title } ](${ url } )` ) ;
80
+ const info : string = markdownEngine . render (
81
+ [
82
+ `| Category | Difficulty | Likes | Dislikes |` ,
83
+ `| :------: | :--------: | :---: | :------: |` ,
84
+ `| ${ category } | ${ difficulty } | ${ likes } | ${ dislikes } |` ,
85
+ ] . join ( "\n" )
86
+ ) ;
87
+ const tags : string = [
88
+ `<details>` ,
89
+ `<summary><strong>Tags</strong></summary>` ,
90
+ markdownEngine . render (
91
+ this . description . tags
92
+ . map ( ( t : string ) => `[\`${ t } \`](https://leetcode.com/tag/${ t } )` )
93
+ . join ( " | " )
94
+ ) ,
95
+ `</details>` ,
96
+ ] . join ( "\n" ) ;
97
+ const companies : string = [
98
+ `<details>` ,
99
+ `<summary><strong>Companies</strong></summary>` ,
100
+ markdownEngine . render (
101
+ this . description . companies . map ( ( c : string ) => `\`${ c } \`` ) . join ( " | " )
102
+ ) ,
103
+ `</details>` ,
104
+ ] . join ( "\n" ) ;
105
+ const links : string = markdownEngine . render (
106
+ `[Discussion](${ this . getDiscussionLink (
107
+ url
108
+ ) } ) | [Solution](${ this . getSolutionLink ( url ) } )`
109
+ ) ;
110
+ return `
103
111
<!DOCTYPE html>
104
112
<html>
105
113
<head>
@@ -126,85 +134,91 @@ class LeetCodePreviewProvider extends LeetCodeWebview {
126
134
</body>
127
135
</html>
128
136
` ;
137
+ }
138
+
139
+ protected onDidDisposeWebview ( ) : void {
140
+ super . onDidDisposeWebview ( ) ;
141
+ this . sideMode = false ;
142
+ }
143
+
144
+ protected async onDidReceiveMessage ( message : IWebViewMessage ) : Promise < void > {
145
+ switch ( message . command ) {
146
+ case "ShowProblem" : {
147
+ await commands . executeCommand ( "leetcode.showProblem" , this . node ) ;
148
+ break ;
149
+ }
129
150
}
130
-
131
- protected onDidDisposeWebview ( ) : void {
132
- super . onDidDisposeWebview ( ) ;
133
- this . sideMode = false ;
151
+ }
152
+
153
+ // private async hideSideBar(): Promise<void> {
154
+ // await commands.executeCommand("workbench.action.focusSideBar");
155
+ // await commands.executeCommand("workbench.action.toggleSidebarVisibility");
156
+ // }
157
+
158
+ private parseDescription ( descString , problem ) {
159
+ // Parse body by looking for the first html tag
160
+ const bodyStartIdx = descString . search ( / < .* > / ) ;
161
+ const bodyRaw = descString . substring ( bodyStartIdx ) ;
162
+
163
+ const { name : title , tags, companies } = problem ;
164
+ return {
165
+ title,
166
+ tags,
167
+ companies,
168
+ url : descString . match ( / h t t p s : .* l e e t c o d e .* / ) ?. [ 0 ] || "??" ,
169
+ category : descString . match ( / \* .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" , // Category is the first element in list
170
+ difficulty : descString . match ( / .* \% .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" , // Difficulty is the first element in list with a percentage sign
171
+ likes :
172
+ descString
173
+ . match ( / L i k e s .* ?\n / ) ?. [ 0 ]
174
+ ?. split ( ": " ) [ 1 ]
175
+ ?. trim ( ) || "0" ,
176
+ dislikes :
177
+ descString
178
+ . match ( / D i s l i k e s .* ?\n / ) ?. [ 0 ]
179
+ ?. split ( ": " ) [ 1 ]
180
+ ?. trim ( ) || "0" ,
181
+ body : bodyRaw . replace (
182
+ / < p r e > [ \r \n ] * ( [ ^ ] + ?) [ \r \n ] * < \/ p r e > / g,
183
+ "<pre><code>$1</code></pre>"
184
+ ) ,
185
+ } ;
186
+ }
187
+
188
+ private getDiscussionLink ( url : string ) : string {
189
+ const endPoint : string = getLeetCodeEndpoint ( ) ;
190
+ if ( endPoint === Endpoint . LeetCodeCN ) {
191
+ return url . replace ( "/description/" , "/comments/" ) ;
192
+ } else if ( endPoint === Endpoint . LeetCode ) {
193
+ return url . replace (
194
+ "/description/" ,
195
+ "/discuss/?currentPage=1&orderBy=most_votes&query="
196
+ ) ;
134
197
}
135
198
136
- protected async onDidReceiveMessage ( message : IWebViewMessage ) : Promise < void > {
137
- switch ( message . command ) {
138
- case "ShowProblem" : {
139
- await commands . executeCommand ( "leetcode.showProblem" , this . node ) ;
140
- break ;
141
- }
142
- }
143
- }
199
+ return "https://leetcode.com" ;
200
+ }
144
201
145
- // private async hideSideBar(): Promise<void> {
146
- // await commands.executeCommand("workbench.action.focusSideBar");
147
- // await commands.executeCommand("workbench.action.toggleSidebarVisibility");
148
- // }
149
-
150
- private parseDescription ( descString : string , problem : IProblem ) : IDescription {
151
- const [
152
- /* title */ , ,
153
- url , ,
154
- /* tags */ , ,
155
- /* langs */ , ,
156
- category ,
157
- difficulty ,
158
- likes ,
159
- dislikes ,
160
- /* accepted */ ,
161
- /* submissions */ ,
162
- /* testcase */ , ,
163
- ...body
164
- ] = descString . split ( "\n" ) ;
165
- return {
166
- title : problem . name ,
167
- url,
168
- tags : problem . tags ,
169
- companies : problem . companies ,
170
- category : category . slice ( 2 ) ,
171
- difficulty : difficulty . slice ( 2 ) ,
172
- likes : likes . split ( ": " ) [ 1 ] . trim ( ) ,
173
- dislikes : dislikes . split ( ": " ) [ 1 ] . trim ( ) ,
174
- body : body . join ( "\n" ) . replace ( / < p r e > [ \r \n ] * ( [ ^ ] + ?) [ \r \n ] * < \/ p r e > / g, "<pre><code>$1</code></pre>" ) ,
175
- } ;
176
- }
177
-
178
- private getDiscussionLink ( url : string ) : string {
179
- const endPoint : string = getLeetCodeEndpoint ( ) ;
180
- if ( endPoint === Endpoint . LeetCodeCN ) {
181
- return url . replace ( "/description/" , "/comments/" ) ;
182
- } else if ( endPoint === Endpoint . LeetCode ) {
183
- return url . replace ( "/description/" , "/discuss/?currentPage=1&orderBy=most_votes&query=" ) ;
184
- }
185
-
186
- return "https://leetcode.com" ;
187
- }
188
-
189
- private getSolutionLink ( url : string ) : string {
190
- return url . replace ( "/description/" , "/solution/" ) ;
191
- }
202
+ private getSolutionLink ( url : string ) : string {
203
+ return url . replace ( "/description/" , "/solution/" ) ;
204
+ }
192
205
}
193
206
194
207
interface IDescription {
195
- title : string ;
196
- url : string ;
197
- tags : string [ ] ;
198
- companies : string [ ] ;
199
- category : string ;
200
- difficulty : string ;
201
- likes : string ;
202
- dislikes : string ;
203
- body : string ;
208
+ title : string ;
209
+ url : string ;
210
+ tags : string [ ] ;
211
+ companies : string [ ] ;
212
+ category : string ;
213
+ difficulty : string ;
214
+ likes : string ;
215
+ dislikes : string ;
216
+ body : string ;
204
217
}
205
218
206
219
interface IWebViewMessage {
207
- command : string ;
220
+ command : string ;
208
221
}
209
222
210
- export const leetCodePreviewProvider : LeetCodePreviewProvider = new LeetCodePreviewProvider ( ) ;
223
+ export const leetCodePreviewProvider : LeetCodePreviewProvider =
224
+ new LeetCodePreviewProvider ( ) ;
0 commit comments