1
+ /*
2
+ * Project Name : Visual Python
3
+ * Description : GUI-based Python code generator
4
+ * File Name : InnerFuncViewer.js
5
+ * Author : Black Logic
6
+ * Note : Component > InnerFuncViewer
7
+ * License : GNU GPLv3 with Visual Python special exception
8
+ * Date : 2022. 06. 14
9
+ * Change Date :
10
+ */
11
+
12
+ //============================================================================
13
+ // [CLASS] InnerFuncViewer
14
+ //============================================================================
15
+ define ( [
16
+ 'text!vp_base/html/component/innerFuncViewer.html!strip' ,
17
+ 'css!vp_base/css/component/innerFuncViewer.css' ,
18
+ 'text!vp_base/python/userCommand.py' ,
19
+ 'vp_base/js/com/com_util' ,
20
+ 'vp_base/js/com/com_String' ,
21
+ 'vp_base/js/com/component/PopupComponent' ,
22
+ 'vp_base/js/com/component/FileNavigation'
23
+ ] , function ( ifHtml , ifCss , userCommandFile , com_util , com_String , PopupComponent , FileNavigation ) {
24
+
25
+ /**
26
+ * InnerFuncViewer
27
+ */
28
+ class InnerFuncViewer extends PopupComponent {
29
+ _init ( ) {
30
+ super . _init ( ) ;
31
+ /** Write codes executed before rendering */
32
+ this . name = 'Inner Function Viewer' ;
33
+ this . config . codeview = false ;
34
+ this . config . dataview = false ;
35
+ this . config . runButton = false ;
36
+ this . config . sizeLevel = 3 ;
37
+
38
+ this . state = {
39
+ vp_userCode : '' ,
40
+ ...this . state
41
+ }
42
+
43
+ this . codemirrorList = { } ;
44
+ this . importedList = [ ] ;
45
+ this . title_no = 0 ;
46
+
47
+ // double click setter
48
+ this . clicked = 0 ;
49
+ }
50
+
51
+ _bindEvent ( ) {
52
+ super . _bindEvent ( ) ;
53
+ /** Implement binding events */
54
+ let that = this ;
55
+
56
+ // search item
57
+ $ ( this . wrapSelector ( '.vp-if-search' ) ) . on ( 'change' , function ( evt ) {
58
+ var value = $ ( this ) . val ( ) ;
59
+ if ( value != '' ) {
60
+ $ ( that . wrapSelector ( '.vp-if-item' ) ) . hide ( ) ;
61
+ $ ( that . wrapSelector ( '.vp-if-item' ) ) . filter ( function ( ) {
62
+ return $ ( this ) . data ( 'title' ) . search ( value ) >= 0 ;
63
+ } ) . show ( ) ;
64
+ } else {
65
+ $ ( that . wrapSelector ( '.vp-if-item' ) ) . show ( ) ;
66
+ }
67
+ } ) ;
68
+ }
69
+
70
+ bindSnippetItem ( ) {
71
+ let that = this ;
72
+ // item header click (toggle item)
73
+ $ ( this . wrapSelector ( '.vp-if-item-header' ) ) . off ( 'click' ) ;
74
+ $ ( this . wrapSelector ( '.vp-if-item-header' ) ) . on ( 'click' , function ( evt ) {
75
+ // select item
76
+ // remove selection
77
+ $ ( that . wrapSelector ( '.vp-if-item-header' ) ) . removeClass ( 'selected' ) ;
78
+ // select item
79
+ $ ( this ) . addClass ( 'selected' ) ;
80
+
81
+ // toggle item
82
+ var parent = $ ( this ) . parent ( ) ;
83
+ var indicator = $ ( parent ) . find ( '.vp-if-indicator' ) ;
84
+ var hasOpen = $ ( indicator ) . hasClass ( 'open' ) ;
85
+
86
+ if ( ! hasOpen ) {
87
+ // show code
88
+ $ ( indicator ) . addClass ( 'open' ) ;
89
+ $ ( parent ) . find ( '.vp-if-item-code' ) . show ( ) ;
90
+ } else {
91
+ // hide code
92
+ $ ( indicator ) . removeClass ( 'open' ) ;
93
+ $ ( parent ) . find ( '.vp-if-item-code' ) . hide ( ) ;
94
+ }
95
+ evt . stopPropagation ( ) ;
96
+ } ) ;
97
+
98
+ // item menu click
99
+ $ ( this . wrapSelector ( '.vp-if-item-menu-item' ) ) . off ( 'click' ) ;
100
+ $ ( this . wrapSelector ( '.vp-if-item-menu-item' ) ) . on ( 'click' , function ( evt ) {
101
+ var menu = $ ( this ) . data ( 'menu' ) ;
102
+ var item = $ ( this ) . closest ( '.vp-if-item' ) ;
103
+ var title = $ ( item ) . data ( 'title' ) ;
104
+ if ( menu == 'run' ) {
105
+ // get codemirror
106
+ let cmCode = that . codemirrorList [ title ] ;
107
+ cmCode . save ( ) ;
108
+ var code = cmCode . getValue ( ) ;
109
+ // create block and run it
110
+ $ ( '#vp_wrapper' ) . trigger ( {
111
+ type : 'create_option_page' ,
112
+ blockType : 'block' ,
113
+ menuId : 'lgExe_code' ,
114
+ menuState : { taskState : { code : code } } ,
115
+ afterAction : 'run'
116
+ } ) ;
117
+ }
118
+ evt . stopPropagation ( ) ;
119
+ } ) ;
120
+ }
121
+
122
+ bindCodeMirror ( title , selector ) {
123
+ let cmCode = this . initCodemirror ( {
124
+ key : title ,
125
+ selector : selector ,
126
+ type : 'readonly' ,
127
+ events : [ {
128
+ key : 'change' ,
129
+ callback : function ( evt , chgObj ) {
130
+ if ( chgObj . removed . join ( '' ) != '' || chgObj . text . join ( '' ) != '' ) {
131
+ // enable save button
132
+ $ ( selector ) . parent ( ) . find ( '.vp-if-save' ) . removeClass ( 'vp-disable' ) ;
133
+ }
134
+ }
135
+ } ]
136
+ } ) ;
137
+ this . codemirrorList [ title ] = cmCode ;
138
+ }
139
+
140
+ templateForBody ( ) {
141
+ return ifHtml ;
142
+ }
143
+
144
+ render ( ) {
145
+ super . render ( ) ;
146
+
147
+ // load udf list
148
+ this . loadUserCommandList ( ) ;
149
+ }
150
+
151
+ renderSnippetItem ( title , code , description ) {
152
+ var item = new com_String ( ) ;
153
+ item . appendFormatLine ( '<div class="{0}" data-title="{1}">' , 'vp-if-item' , title , title ) ;
154
+ item . appendFormatLine ( '<div class="{0}" title="{1}">' , 'vp-if-item-header' , description ) ;
155
+ item . appendFormatLine ( '<div class="{0}"></div>' , 'vp-if-indicator' ) ;
156
+ item . appendFormatLine ( '<input type="text" class="vp-input {0}" value="{1}" disabled/>' , 'vp-if-item-title' , title ) ;
157
+ item . appendFormatLine ( '<div class="{0}">' , 'vp-if-item-menu' ) ;
158
+ item . appendFormatLine ( '<div class="{0}" data-menu="{1}" title="{2}">'
159
+ , 'vp-if-item-menu-item' , 'run' , 'Run' ) ;
160
+ item . appendFormatLine ( '<img src="{0}"/>' , '/nbextensions/visualpython/img/snippets/run.svg' ) ;
161
+ item . appendLine ( '</div>' ) ;
162
+ item . appendLine ( '</div>' ) ; // end of vp-if-item-menu
163
+ item . appendLine ( '</div>' ) ; // end of vp-if-item-header
164
+ item . appendFormatLine ( '<div class="{0}">' , 'vp-if-item-code' ) ;
165
+ item . appendFormatLine ( '<textarea>{0}</textarea>' , code ) ;
166
+ item . appendLine ( '</div>' ) ; // end of vp-if-item-code
167
+ item . appendLine ( '</div>' ) ; // end of vp-if-item
168
+ return item . toString ( ) ;
169
+ }
170
+
171
+ generateCode ( ) {
172
+ return '' ;
173
+ }
174
+
175
+ loadUserCommandList ( ) {
176
+ var that = this ;
177
+
178
+ let divider = '#' . repeat ( 6 ) ;
179
+ // get list of codes (ignore first 2 items)
180
+ let tmpList = userCommandFile . split ( divider ) . slice ( 2 ) ;
181
+
182
+ // match key-codes-description
183
+ // { 'func_name': { code: '', description: '' } }
184
+ let funcDict = { } ;
185
+ let reg = / ^ d e f ( .+ ) \( / ;
186
+ let name = '' ;
187
+ let code = '' ;
188
+ let desc = '' ;
189
+
190
+ for ( let i = 0 ; i < tmpList . length ; i += 2 ) {
191
+ desc = tmpList [ i ] . trim ( ) ;
192
+ code = tmpList [ i + 1 ] . trim ( ) ;
193
+ let regResult = reg . exec ( code ) ;
194
+ if ( regResult !== null ) {
195
+ name = regResult [ 1 ] ;
196
+ funcDict [ name ] = { code : code , description : desc } ;
197
+ }
198
+ }
199
+
200
+ // clear table except head
201
+ $ ( this . wrapSelector ( '.vp-if-table' ) ) . html ( '' ) ;
202
+
203
+ // load code list
204
+ var innerFuncCode = new com_String ( ) ;
205
+ Object . keys ( funcDict ) . forEach ( key => {
206
+ let obj = funcDict [ key ] ;
207
+ if ( obj . code != null && obj . code != undefined ) {
208
+ var item = that . renderSnippetItem ( key , obj . code , obj . description ) ;
209
+ innerFuncCode . append ( item ) ;
210
+ }
211
+ } ) ;
212
+ $ ( that . wrapSelector ( '.vp-if-table' ) ) . html ( innerFuncCode . toString ( ) ) ;
213
+
214
+ // bind snippet item
215
+ that . bindSnippetItem ( ) ;
216
+
217
+ // load codemirror
218
+ var codeList = $ ( that . wrapSelector ( '.vp-if-item-code textarea' ) ) ;
219
+ codeList . each ( ( idx , tag ) => {
220
+ var title = $ ( tag ) . closest ( '.vp-if-item' ) . data ( 'title' ) ;
221
+ that . bindCodeMirror ( title , tag ) ;
222
+ } ) ;
223
+ }
224
+
225
+ }
226
+
227
+ return InnerFuncViewer ;
228
+ } ) ;
0 commit comments