1
0
mirror of https://github.com/pyscript/pyscript.git synced 2022-05-01 19:47:48 +03:00

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

@@ -32,6 +32,7 @@ export class BaseEvalElement extends HTMLElement {
shadow: ShadowRoot;
wrapper: HTMLElement;
code: string;
source: string;
btnConfig: HTMLElement;
btnRun: HTMLElement;
outputElement: HTMLElement; //HTMLTextAreaElement;
@@ -55,10 +56,17 @@ export class BaseEvalElement extends HTMLElement {
}
getSource(): string{
getSourceFromElement(): string{
return "";
}
async getSourceFromFile(s: string): Promise<string>{
let pyodide = await pyodideReadyPromise;
let response = await fetch(s);
this.code = await response.text();
return this.code;
}
protected async _register_esm(pyodide: PyodideInterface): Promise<void> {
const imports: {[key: string]: unknown} = {}
@@ -91,53 +99,44 @@ export class BaseEvalElement extends HTMLElement {
pyodide.registerJsModule("esm", imports)
}
async evaluate() {
async evaluate(): Promise<void> {
console.log('evaluate');
let pyodide = await pyodideReadyPromise;
try {
let pyodide = await pyodideReadyPromise;
let source: string;
let output;
try {
// @ts-ignore
const source = this.getSource();
await this._register_esm(pyodide)
let output;
if (this.source){
source = await this.getSourceFromFile(this.source);
}else{
source = this.getSourceFromElement();
}
await this._register_esm(pyodide);
if (source.includes("asyncio")){
output = await pyodide.runPythonAsync(source);
await pyodide.runPythonAsync(`output_manager.revert()`)
output = await pyodide.runPythonAsync(source);
await pyodide.runPythonAsync(`output_manager.revert()`)
}else{
output = pyodide.runPython(source);
pyodide.runPython(`output_manager.revert()`)
output = pyodide.runPython(source);
pyodide.runPython(`output_manager.revert()`)
}
if (output !== undefined){
if (Element === undefined){
if (Element === undefined){
Element = pyodide.globals.get('Element');
}
const out = Element(this.outputElement.id);
// @ts-ignore
out.write.callKwargs(output, { append : true});
}
const out = Element(this.outputElement.id);
// @ts-ignore
out.write.callKwargs(output, { append : true});
if (!this.hasAttribute('target')) {
if (!this.hasAttribute('target')) {
this.outputElement.hidden = false;
}
}
}
this.postEvaluate()
this.postEvaluate()
// if (this.hasAttribute('auto-generate')) {
// let nextExecId = parseInt(this.getAttribute('exec-id')) + 1;
// const newPyRepl = document.createElement("py-repl");
// newPyRepl.setAttribute('root', this.getAttribute('root'));
// newPyRepl.id = this.getAttribute('root') + "-" + nextExecId.toString();
// newPyRepl.setAttribute('auto-generate', null);
// if (this.hasAttribute('target')){
// newPyRepl.setAttribute('target', this.getAttribute('target'));
// }
// newPyRepl.setAttribute('exec-id', nextExecId.toString());
// this.parentElement.appendChild(newPyRepl);
// }
} catch (err) {
this.addToOutput(err);
}

View File

@@ -204,7 +204,7 @@ export class PyRepl extends BaseEvalElement {
}
}
getSource(): string {
getSourceFromElement(): string {
const sourceStrings = [`output_manager.change("`+this.outputElement.id+`")`,
...this.editor.state.doc.toString().split("\n")];
return sourceStrings.join('\n')

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;
}
}