@@ -151,3 +151,171 @@ export class BaseEvalElement extends HTMLElement {
151
151
}
152
152
}
153
153
}
154
+
155
+ function createWidget ( name : string , code : string , klass : string ) {
156
+
157
+
158
+ class CustomWidget extends HTMLElement {
159
+ shadow : ShadowRoot ;
160
+ wrapper : HTMLElement ;
161
+
162
+ name : string = name ;
163
+ klass : string = klass ;
164
+ code : string = code ;
165
+ proxy : any ;
166
+ proxyClass : any ;
167
+
168
+ constructor ( ) {
169
+ super ( ) ;
170
+
171
+ // attach shadow so we can preserve the element original innerHtml content
172
+ this . shadow = this . attachShadow ( { mode : 'open' } ) ;
173
+
174
+ this . wrapper = document . createElement ( 'slot' ) ;
175
+ this . shadow . appendChild ( this . wrapper ) ;
176
+ }
177
+
178
+ connectedCallback ( ) {
179
+ console . log ( this . name , 'connected!!!!' )
180
+ this . eval ( this . code ) . then ( ( ) => {
181
+ this . proxy = this . proxyClass ( this ) ;
182
+ console . log ( 'proxy' , this . proxy ) ;
183
+ this . proxy . connect ( ) ;
184
+ this . registerWidget ( ) ;
185
+ } ) ;
186
+ }
187
+
188
+ async registerWidget ( ) {
189
+ let pyodide = await pyodideReadyPromise ;
190
+
191
+ console . log ( 'new widget registered:' , this . name ) ;
192
+
193
+
194
+ pyodide . globals . set ( this . id , this . proxy ) ;
195
+ }
196
+
197
+
8000
async eval ( source : string ) : Promise < void > {
198
+ let output ;
199
+ let pyodide = await pyodideReadyPromise ;
200
+ try {
201
+ output = await pyodide . runPythonAsync ( source ) ;
202
+ this . proxyClass = pyodide . globals . get ( this . klass ) ;
203
+ if ( output !== undefined ) {
204
+ console . log ( output ) ;
205
+ }
206
+
207
+ } catch ( err ) {
208
+ console . log ( err ) ;
209
+ }
210
+ }
211
+ }
212
+ let xPyWidget = customElements . define ( name , CustomWidget ) ;
213
+ }
214
+
215
+ export class PyWidget extends HTMLElement {
216
+ shadow : ShadowRoot ;
217
+ name : string ;
218
+ klass : string ;
219
+ outputElement : HTMLElement ;
220
+ errorElement : HTMLElement ;
221
+ wrapper : HTMLElement ;
222
+ theme : string ;
223
+ source : string ;
224
+ code : string ;
225
+
226
+ constructor ( ) {
227
+ super ( ) ;
228
+
229
+ // attach shadow so we can preserve the element original innerHtml content
230
+ this . shadow = this . attachShadow ( { mode : 'open' } ) ;
231
+
232
+ this . wrapper = document . createElement ( 'slot' ) ;
233
+ this . shadow . appendChild ( this . wrapper ) ;
234
+
235
+ if ( this . hasAttribute ( 'src' ) ) {
236
+ this . source = this . getAttribute ( 'src' ) ;
237
+ }
238
+
239
+ if ( this . hasAttribute ( 'name' ) ) {
240
+ this . name = this . getAttribute ( 'name' ) ;
241
+ }
242
+
243
+ if ( this . hasAttribute ( 'klass' ) ) {
244
+ this . klass = this . getAttribute ( 'klass' ) ;
245
+ }
246
+ }
247
+
248
+
249
+ connectedCallback ( ) {
250
+ if ( this . id === undefined ) {
251
+ throw new ReferenceError ( `No id specified for component. Components must have an explicit id. Please use id="" to specify your component id.` )
252
+ return ;
253
+ }
254
+
255
+ let mainDiv = document . createElement ( 'div' ) ;
256
+ mainDiv . id = this . id + '-main' ;
257
+ this . appendChild ( mainDiv ) ;
258
+ console . log ( 'reading source' )
259
+ this . getSourceFromFile ( this . source ) . then ( ( code :string ) => {
260
+ this . code = code ;
261
+ createWidget ( this . name , code , this . klass ) ;
262
+
263
+ } ) ;
264
+
265
+ console . log ( 'py-template connected' ) ;
266
+ }
267
+
268
+ initOutErr ( ) : void {
269
+ if ( this . hasAttribute ( 'output' ) ) {
270
+ this . errorElement = this . outputElement = document . getElementById ( this . getAttribute ( 'output' ) ) ;
271
+
272
+ // in this case, the default output-mode is append, if hasn't been specified
273
+ if ( ! this . hasAttribute ( 'output-mode' ) ) {
274
+ this . setAttribute ( 'output-mode' , 'append' ) ;
275
+ }
276
+ } else {
277
+ if ( this . hasAttribute ( 'std-out' ) ) {
278
+ this . outputElement = document . getElementById ( this . getAttribute ( 'std-out' ) ) ;
279
+ } else {
280
+ // In this case neither output or std-out have been provided so we need
281
+ // to create a new output div to output to
282
+ this . outputElement = document . createElement ( 'div' ) ;
283
+ this . outputElement . classList . add ( "output" ) ;
284
+ this . outputElement . hidden = true ;
285
+ this . outputElement . id = this . id + "-" + this . getAttribute ( "exec-id" ) ;
286
+
287
+ // add the output div id if there's not output pre-defined
288
+ //mainDiv.appendChild(this.outputElement);
289
+ }
290
+
291
+ if ( this . hasAttribute ( 'std-err' ) ) {
292
+ this . outputElement = document . getElementById ( this . getAttribute ( 'std-err' ) ) ;
293
+ } else {
294
+ this . errorElement = this . outputElement ;
295
+ }
296
+ }
297
+ }
298
+
299
+ async getSourceFromFile ( s : string ) : Promise < string > {
300
+ let pyodide = await pyodideReadyPromise ;
301
+ let response = await fetch ( s ) ;
302
+ return await response . text ( ) ;
303
+ }
304
+
305
+ async eval ( source : string ) : Promise < void > {
306
+ let output ;
307
+ let pyodide = await pyodideReadyPromise ;
308
+ try {
309
+ output = await pyodide . runPythonAsync ( source ) ;
310
+
311
+ if ( output !== undefined ) {
312
+ console . log ( output ) ;
313
+ }
314
+
315
+ } catch ( err ) {
316
+ console . log ( err ) ;
317
+ }
318
+ }
319
+
320
+
321
+ }
0 commit comments