adapt pyscript to new base class and clean Base

This commit is contained in:
Fabio Pliger
2022-04-18 12:06:30 -05:00
parent 955fb6fd37
commit 4d890602d9
3 changed files with 46 additions and 131 deletions

View File

@@ -8,6 +8,7 @@ import { oneDarkTheme } from "@codemirror/theme-one-dark";
import { pyodideLoaded, loadedEnvironments, componentDetailsNavOpen, currentComponentDetails, mode, addToScriptsQueue, addInitializer, addPostInitializer } from '../stores';
import { addClasses } from '../utils';
import { BaseEvalElement } from './base';
// Premise used to connect to the first available pyodide interpreter
let pyodideReadyPromise;
@@ -50,6 +51,8 @@ type PyodideInterface = {
registerJsModule(name: string, module: object): void
}
// TODO: This should be used as base for generic scripts that need exectutoin
// from PyScript to initializers, etc...
class Script {
source: string;
state: string;
@@ -90,30 +93,13 @@ class Script {
}
}
export class PyScript extends HTMLElement {
shadow: ShadowRoot;
wrapper: HTMLElement;
editor: EditorView;
editorNode: HTMLElement;
code: string;
cm: any;
btnConfig: HTMLElement;
btnRun: HTMLElement;
editorOut: HTMLElement; //HTMLTextAreaElement;
source: string;
export class PyScript extends BaseEvalElement {
// editorState: EditorState;
constructor() {
super();
// attach shadow so we can preserve the element original innerHtml content
this.shadow = this.attachShadow({ mode: 'open'});
this.wrapper = document.createElement('slot');
// add an extra div where we can attach the codemirror editor
this.editorNode = document.createElement('div');
addClasses(this.editorNode, ["editor-box"])
this.shadow.appendChild(this.wrapper);
}
@@ -140,11 +126,6 @@ export class PyScript extends HTMLElement {
]
})
this.editor = new EditorView({
state: startState,
parent: this.editorNode
})
let mainDiv = document.createElement('div');
addClasses(mainDiv, ["parentBox", "flex", "flex-col", "border-4", "border-dashed", "border-gray-200", "rounded-lg"])
// add Editor to main PyScript div
@@ -190,18 +171,17 @@ export class PyScript extends HTMLElement {
eDiv.appendChild(this.btnConfig);
mainDiv.appendChild(eDiv);
mainDiv.appendChild(this.editorNode);
if (this.hasAttribute('target')) {
this.editorOut = document.getElementById(this.getAttribute('target'));
this.outputElement = document.getElementById(this.getAttribute('target'));
}else{
// Editor Output Div
this.editorOut = document.createElement('div');
this.editorOut.classList.add("output");
this.editorOut.hidden = true;
this.outputElement = document.createElement('div');
this.outputElement.classList.add("output");
this.outputElement.hidden = true;
// add the output div id there's not target
mainDiv.appendChild(this.editorOut);
mainDiv.appendChild(this.outputElement);
}
if (currentMode=="edit"){
@@ -217,35 +197,6 @@ export class PyScript extends HTMLElement {
}
}
addToOutput(s: string) {
this.editorOut.innerHTML = s;
this.editorOut.hidden = false;
}
async loadFromFile(s: string){
let pyodide = await pyodideReadyPromise;
let response = await fetch(s);
this.code = await response.text();
await pyodide.runPythonAsync(this.code);
await pyodide.runPythonAsync(`
from pyodide.http import pyfetch
from pyodide import eval_code
response = await pyfetch("`+s+`")
content = await response.bytes()
with open("todo.py", "wb") as f:
print(content)
f.write(content)
print("done writing")
`)
// let pkg = pyodide.pyimport("todo");
// pyodide.runPython(`
// import todo
// `)
// pkg.do_something();
}
protected async _register_esm(pyodide: PyodideInterface): Promise<void> {
const imports: {[key: string]: unknown} = {}
@@ -278,43 +229,8 @@ export class PyScript extends HTMLElement {
pyodide.registerJsModule("esm", imports)
}
async evaluate(): Promise<void> {
console.log('evaluate');
if (this.source){
this.loadFromFile(this.source)
}else{
const pyodide = await pyodideReadyPromise;
await this._register_esm(pyodide)
// debugger
try {
// @ts-ignore
const source = htmlDecode(this.editor.state.doc.toString());
let output;
if (source.includes("asyncio")){
output = await pyodide.runPythonAsync(source);
}else{
output = pyodide.runPython(source);
}
if (output !== undefined){
this.addToOutput(output);
}
if (this.hasAttribute('auto-generate') && this.parentElement.lastChild === this) {
const newPyscript = document.createElement("py-script");
newPyscript.setAttribute('auto-generate', null);
this.parentElement.appendChild(newPyscript);
}
} catch (err) {
this.addToOutput(err);
console.log(err);
}
}
}
render(){
console.log('rendered');
getSourceFromElement(): string {
return this.code;
}
}