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" ;
55import { leetCodeExecutor } from "../leetCodeExecutor" ;
66import { IProblem } from "../shared" ;
7+ import { ILeetCodeWebviewOption , LeetCodeWebview } from "./LeetCodeWebview" ;
78import { markdownEngine } from "./markdownEngine" ;
89
9- class LeetCodePreviewProvider implements Disposable {
10+ class LeetCodePreviewProvider extends LeetCodeWebview {
1011
11- private context : ExtensionContext ;
1212 private node : IProblem ;
13- private panel : WebviewPanel | undefined ;
14-
15- public initialize ( context : ExtensionContext ) : void {
16- this . context = context ;
17- }
13+ private description : IDescription ;
1814
1915 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 ) ;
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- 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 ( ) ;
5119 }
5220
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 {
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 ( / < 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 ,
8426 } ;
8527 }
8628
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>
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 const head : string = markdownEngine . render ( `# [${ title } ](${ url } )` ) ;
11157 const info : 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 id="solve">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+ 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+ }
162147}
163148
164149interface IDescription {
0 commit comments