1+ import './style.css' ;
2+ import CodeMirror from 'codemirror' ;
3+ import 'codemirror/mode/python/python' ;
4+ import 'codemirror/addon/comment/comment' ;
5+ import 'codemirror/lib/codemirror.css' ;
6+
7+ let rp ;
8+
9+ // UI elements
10+ const consoleElement = document . getElementById ( 'console' ) ;
11+ const errorElement = document . getElementById ( 'error' ) ;
12+ const fetchbtnElement = document . getElementById ( "fetch-code" ) ;
13+ const urlConainerElement = document . getElementById ( 'url-container' ) ;
14+
15+ // A dependency graph that contains any wasm must be imported asynchronously.
16+ import ( 'rustpython' )
17+ . then ( rustpy => {
18+ rp = rustpy ;
19+ // so people can play around with it
20+ window . rp = rustpy ;
21+ onReady ( ) ;
22+ } )
23+ . catch ( e => {
24+ console . error ( 'Error importing `rustpython`:' , e ) ;
25+ document . getElementById ( 'error' ) . textContent = e ;
26+ } ) ;
27+
28+ // Code Mirror code editor
29+ const editor = CodeMirror . fromTextArea ( document . getElementById ( 'code' ) , {
30+ extraKeys : {
31+ 'Ctrl-Enter' : runCodeFromTextarea ,
32+ 'Cmd-Enter' : runCodeFromTextarea ,
33+ 'Shift-Tab' : 'indentLess' ,
34+ 'Ctrl-/' : 'toggleComment' ,
35+ 'Cmd-/' : 'toggleComment' ,
36+ Tab : editor => {
37+ var spaces = Array ( editor . getOption ( 'indentUnit' ) + 1 ) . join ( ' ' ) ;
38+ editor . replaceSelection ( spaces ) ;
39+ }
40+ } ,
41+ lineNumbers : true ,
42+ mode : 'text/x-python' ,
43+ indentUnit : 4 ,
44+ autofocus : true
45+ } ) ;
46+
47+ // Runs the code the the code editor
48+ function runCodeFromTextarea ( ) {
49+ // Clean the console and errors
50+ consoleElement . innerHTML = '' ;
51+ errorElement . textContent = '' ;
52+
53+ const code = editor . getValue ( ) ;
54+ try {
55+ rp . pyExec ( code , {
56+ stdout : output => {
57+ consoleElement . innerHTML += output ;
58+ }
59+ } ) ;
60+ } catch ( err ) {
61+ if ( err instanceof WebAssembly . RuntimeError ) {
62+ err = window . __RUSTPYTHON_ERROR || err ;
63+ }
64+ errorElement . textContent = err ;
65+ console . error ( err ) ;
66+ }
67+ }
68+
69+ function onReady ( ) {
70+ // snippets.addEventListener('change', updateSnippet);
71+ document
72+ . getElementById ( 'run-btn' )
73+ . addEventListener ( 'click' , runCodeFromTextarea ) ;
74+
75+ // so that the test knows that we're ready
76+ const readyElement = document . createElement ( 'div' ) ;
77+ readyElement . id = 'rp_loaded' ;
78+ document . head . appendChild ( readyElement ) ;
79+ }
80+
81+ // when clicking the import code button
82+ // show a UI with a url input + fetch button
83+ // only accepts api.github.com urls (for now)
84+ // add another function to parse a regular url
85+ fetchbtnElement . addEventListener ( "click" , function ( ) {
86+ // https://developer.github.com/v3/repos/contents/#get-repository-content
87+ // Format:
88+ // https://api.github.com/repos/username/reponame/contents/filename.py
89+ let url = document
90+ . getElementById ( 'snippet-url' )
91+ . value ;
92+ // minimal js fetch code
93+ // needs better error handling
94+ fetch ( url )
95+ . then ( res => res . json ( ) )
96+ . then ( data => {
97+ // The Python code is in data.content
98+ // it is encoded with Base64. Use atob to decode it.
99+ //https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob
100+ var decodedData = atob ( data . content ) ;
101+ // set the value of the code editor
102+ editor . setValue ( decodedData ) ;
103+ urlConainerElement . classList . add ( "d-none" ) ;
104+ } ) . catch ( err => {
105+ document
106+ . getElementById ( "errors" )
107+ . innerHTML = "Couldn't fetch code. Make sure the link is public."
108+ } ) ;
109+
110+ } ) ;
111+
112+ document . getElementById ( "snippet-btn" ) . addEventListener ( "click" , function ( ) {
113+ urlConainerElement . classList . remove ( "d-none" ) ;
114+ } ) ;
0 commit comments