@@ -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>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>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,87 +134,94 @@ 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 ;
134
- }
135
-
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
- }
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 is the first element in list
170
+ category :descString . match ( / \* .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" ,
171
+ // Difficulty is the first element in list with a percentage sign
172
+ difficulty :descString . match ( / .* \% .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" ,
173
+ likes :
174
+ descString
175
+ . match ( / L i k e s .* ?\n / ) ?. [ 0 ]
176
+ ?. split ( ": " ) [ 1 ]
177
+ ?. trim ( ) || "0" ,
178
+ dislikes :
179
+ descString
180
+ . match ( / D i s l i k e s .* ?\n / ) ?. [ 0 ]
181
+ ?. split ( ": " ) [ 1 ]
182
+ ?. trim ( ) || "0" ,
183
+ body :bodyRaw . replace (
184
+ / < p r e > [ \r \n ] * ( [ ^ ] + ?) [ \r \n ] * < \/ p r e > / g,
185
+ "<pre><code>$1</code></pre>"
186
+ ) ,
187
+ } ;
188
+ }
189
+
190
+ private getDiscussionLink ( url :string ) :string {
191
+ const endPoint :string = getLeetCodeEndpoint ( ) ;
192
+ if ( endPoint === Endpoint . LeetCodeCN ) {
193
+ return url . replace ( "/description/" , "/comments/" ) ;
194
+ } else if ( endPoint === Endpoint . LeetCode ) {
195
+ return url . replace (
196
+ "/description/" ,
197
+ "/discuss/?currentPage=1&orderBy=most_votes&query="
198
+ ) ;
143
199
}
144
200
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 , problem ) {
151
- // Parse body by looking for the first html tag
152
- const bodyStartIdx = descString . search ( / < .* > / ) ;
153
- const bodyRaw = descString . substring ( bodyStartIdx ) ;
154
-
155
- const { name :title , tags, companies} = problem ;
156
- return {
157
- title,
158
- tags,
159
- companies,
160
- url :descString . match ( / h t t p s : .* l e e t c o d e .* / ) ?. [ 0 ] || "??" ,
161
- category :descString . match ( / \* .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" , // Category is the first element in list
162
- difficulty :descString . match ( / .* \% .* / ) ?. [ 0 ] ?. slice ( 2 ) || "??" , // Difficulty is the first element in list with a percentage sign
163
- likes :
164
- descString
165
- . match ( / L i k e s .* ?\n / ) ?. [ 0 ]
166
- ?. split ( ": " ) [ 1 ]
167
- ?. trim ( ) || "0" ,
168
- dislikes :
169
- descString
170
- . match ( / D i s l i k e s .* ?\n / ) ?. [ 0 ]
171
- ?. split ( ": " ) [ 1 ]
172
- ?. trim ( ) || "0" ,
173
- body :bodyRaw . replace (
174
- / < p r e > [ \r \n ] * ( [ ^ ] + ?) [ \r \n ] * < \/ p r e > / g,
175
- "<pre><code>$1</code></pre>"
176
- ) ,
177
- } ;
178
- }
179
- private getDiscussionLink ( url :string ) :string {
180
- const endPoint :string = getLeetCodeEndpoint ( ) ;
181
- if ( endPoint === Endpoint . LeetCodeCN ) {
182
- return url . replace ( "/description/" , "/comments/" ) ;
183
- } else if ( endPoint === Endpoint . LeetCode ) {
184
- return url . replace ( "/description/" , "/discuss/?currentPage=1&orderBy=most_votes&query=" ) ;
185
- }
186
-
187
- return "https://leetcode.com" ;
188
- }
201
+ return "https://leetcode.com" ;
202
+ }
189
203
190
- private getSolutionLink ( url :string ) :string {
191
- return url . replace ( "/description/" , "/solution/" ) ;
192
- }
204
+ private getSolutionLink ( url :string ) :string {
205
+ return url . replace ( "/description/" , "/solution/" ) ;
206
+ }
193
207
}
194
208
195
209
interface IDescription {
196
- title :string ;
197
- url :string ;
198
- tags :string [ ] ;
199
- companies :string [ ] ;
200
- category :string ;
201
- difficulty :string ;
202
- likes :string ;
203
- dislikes :string ;
204
- body :string ;
210
+ title :string ;
211
+ url :string ;
212
+ tags :string [ ] ;
213
+ companies :string [ ] ;
214
+ category :string ;
215
+ difficulty :string ;
216
+ likes :string ;
217
+ dislikes :string ;
218
+ body :string ;
205
219
}
206
220
207
221
interface IWebViewMessage {
208
- command :string ;
222
+ command :string ;
209
223
}
210
224
211
- export const leetCodePreviewProvider :LeetCodePreviewProvider = new LeetCodePreviewProvider ( ) ;
225
+ export const leetCodePreviewProvider :LeetCodePreviewProvider =
226
+ new LeetCodePreviewProvider ( ) ;
212
227