[PYS-12] Format and lint

This commit is contained in:
Ross Bermudez
2022-04-25 14:57:00 +02:00
parent 6f8f978ef7
commit 27deee3f86
17 changed files with 874 additions and 863 deletions

View File

@@ -1,12 +1,19 @@
import {EditorState, EditorView, basicSetup} from "@codemirror/basic-setup"
import { python } from "@codemirror/lang-python"
// @ts-ignore
import { EditorState } from '@codemirror/basic-setup';
import { python } from '@codemirror/lang-python';
import { StateCommand } from '@codemirror/state';
import { keymap, ViewUpdate } from "@codemirror/view";
import { defaultKeymap } from "@codemirror/commands";
import { oneDarkTheme } from "@codemirror/theme-one-dark";
import { keymap } from '@codemirror/view';
import { defaultKeymap } from '@codemirror/commands';
import { oneDarkTheme } from '@codemirror/theme-one-dark';
import { pyodideLoaded, loadedEnvironments, componentDetailsNavOpen, currentComponentDetails, mode, addToScriptsQueue, addInitializer, addPostInitializer } from '../stores';
import {
addInitializer,
addPostInitializer,
addToScriptsQueue,
componentDetailsNavOpen,
loadedEnvironments,
mode,
pyodideLoaded,
} from '../stores';
import { addClasses, htmlDecode } from '../utils';
import { BaseEvalElement } from './base';
@@ -17,7 +24,7 @@ let currentMode;
let handlersCollected = false;
pyodideLoaded.subscribe(value => {
pyodideReadyPromise = value;
pyodideReadyPromise = value;
});
loadedEnvironments.subscribe(value => {
environments = value;
@@ -25,240 +32,233 @@ loadedEnvironments.subscribe(value => {
let propertiesNavOpen;
componentDetailsNavOpen.subscribe(value => {
propertiesNavOpen = value;
propertiesNavOpen = value;
});
mode.subscribe(value => {
currentMode = value;
currentMode = value;
});
function createCmdHandler(el){
function createCmdHandler(el) {
// Creates a codemirror cmd handler that calls the el.evaluate when an event
// triggers that specific cmd
const toggleCheckbox:StateCommand = ({ state, dispatch }) => {
return el.evaluate(state)
}
return toggleCheckbox
const toggleCheckbox: StateCommand = ({ state, dispatch }) => {
return el.evaluate(state);
};
return toggleCheckbox;
}
// TODO: use type declaractions
type PyodideInterface = {
registerJsModule(name: string, module: object): void
}
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;
output: string;
constructor(source: string, output: string) {
this.output = output;
this.source = source;
this.state = 'waiting';
}
async evaluate() {
console.log('evaluate');
let pyodide = await pyodideReadyPromise;
// debugger
try {
// @ts-ignore
// let source = this.editor.state.doc.toString();
let output;
if (this.source.includes("asyncio")){
output = await pyodide.runPythonAsync(this.source);
}else{
output = pyodide.runPython(this.source);
}
source: string;
state: string;
output: string;
if (this.output){
// this.editorOut.innerHTML = s;
}
// if (output !== undefined){
// this.addToOutput(output);
// }
constructor(source: string, output: string) {
this.output = output;
this.source = source;
this.state = 'waiting';
}
} catch (err) {
console.log("OOOPS, this happened: " + err);
// this.addToOutput(err);
}
}
async evaluate() {
console.log('evaluate');
const pyodide = await pyodideReadyPromise;
// debugger
try {
// let source = this.editor.state.doc.toString();
let output;
if (this.source.includes('asyncio')) {
output = await pyodide.runPythonAsync(this.source);
} else {
output = pyodide.runPython(this.source);
}
if (this.output) {
// this.editorOut.innerHTML = s;
}
// if (output !== undefined){
// this.addToOutput(output);
// }
} catch (err) {
console.log('OOOPS, this happened: ', err);
// this.addToOutput(err);
}
}
}
export class PyScript extends BaseEvalElement {
constructor() {
super();
// add an extra div where we can attach the codemirror editor
this.shadow.appendChild(this.wrapper);
}
}
connectedCallback() {
this.checkId()
this.checkId();
this.code = this.innerHTML;
this.innerHTML = '';
let startState = EditorState.create({
doc: this.code,
extensions: [
keymap.of([
const startState = EditorState.create({
doc: this.code,
extensions: [
keymap.of([
...defaultKeymap,
{ key: "Ctrl-Enter", run: createCmdHandler(this) },
{ key: "Shift-Enter", run: createCmdHandler(this) }
]),
oneDarkTheme,
python(),
// Event listener function that is called every time an user types something on this editor
// EditorView.updateListener.of((v:ViewUpdate) => {
// if (v.docChanged) {
// console.log(v.changes);
{ key: 'Ctrl-Enter', run: createCmdHandler(this) },
{ key: 'Shift-Enter', run: createCmdHandler(this) },
]),
oneDarkTheme,
python(),
// Event listener function that is called every time an user types something on this editor
// EditorView.updateListener.of((v:ViewUpdate) => {
// if (v.docChanged) {
// console.log(v.changes);
// }
// })
]
})
let mainDiv = document.createElement('div');
addClasses(mainDiv, ["parentBox", "flex", "flex-col", 'mx-8'])
// add Editor to main PyScript div
// }
// })
],
});
if (this.hasAttribute('output')) {
this.errorElement = this.outputElement = document.getElementById(this.getAttribute('output'));
const mainDiv = document.createElement('div');
addClasses(mainDiv, ['parentBox', 'flex', 'flex-col', 'mx-8']);
// add Editor to main PyScript div
// in this case, the default output-mode is append, if hasn't been specified
if (!this.hasAttribute('output-mode')) {
this.setAttribute('output-mode', 'append');
}
}else{
if (this.hasAttribute('std-out')){
this.outputElement = document.getElementById(this.getAttribute('std-out'));
}else{
// In this case neither output or std-out have been provided so we need
// to create a new output div to output to
if (this.hasAttribute('output')) {
this.errorElement = this.outputElement = document.getElementById(this.getAttribute('output'));
// Let's check if we have an id first and create one if not
this.outputElement = document.createElement('div');
const exec_id = this.getAttribute("exec-id");
this.outputElement.id = this.id + (exec_id ? "-"+exec_id : "");
// in this case, the default output-mode is append, if hasn't been specified
if (!this.hasAttribute('output-mode')) {
this.setAttribute('output-mode', 'append');
}
} else {
if (this.hasAttribute('std-out')) {
this.outputElement = document.getElementById(this.getAttribute('std-out'));
} else {
// In this case neither output or std-out have been provided so we need
// to create a new output div to output to
// add the output div id if there's not output pre-defined
mainDiv.appendChild(this.outputElement);
// Let's check if we have an id first and create one if not
this.outputElement = document.createElement('div');
const exec_id = this.getAttribute('exec-id');
this.outputElement.id = this.id + (exec_id ? '-' + exec_id : '');
// add the output div id if there's not output pre-defined
mainDiv.appendChild(this.outputElement);
}
if (this.hasAttribute('std-err')) {
this.outputElement = document.getElementById(this.getAttribute('std-err'));
} else {
this.errorElement = this.outputElement;
}
}
if (this.hasAttribute('std-err')){
this.outputElement = document.getElementById(this.getAttribute('std-err'));
}else{
this.errorElement = this.outputElement;
if (currentMode == 'edit') {
// TODO: We need to build a plan for this
this.appendChild(mainDiv);
} else {
this.appendChild(mainDiv);
addToScriptsQueue(this);
}
}
if (currentMode=="edit"){
// TODO: We need to build a plan for this
this.appendChild(mainDiv);
}else{
this.appendChild(mainDiv);
addToScriptsQueue(this);
}
console.log('connected');
console.log('connected');
if (this.hasAttribute('src')) {
this.source = this.getAttribute('src');
}
if (this.hasAttribute('src')) {
this.source = this.getAttribute('src');
}
}
protected async _register_esm(pyodide: PyodideInterface): Promise<void> {
for (const node of document.querySelectorAll("script[type='importmap']")) {
const importmap = (() => {
try {
return JSON.parse(node.textContent)
} catch {
return null
}
})()
for (const node of document.querySelectorAll("script[type='importmap']")) {
const importmap = (() => {
try {
return JSON.parse(node.textContent);
} catch {
return null;
}
})();
if (importmap?.imports == null)
continue
if (importmap?.imports == null) continue;
for (const [name, url] of Object.entries(importmap.imports)) {
if (typeof name != "string" || typeof url != "string")
continue
for (const [name, url] of Object.entries(importmap.imports)) {
if (typeof name != 'string' || typeof url != 'string') continue;
let exports: object
try {
// XXX: pyodide doesn't like Module(), failing with
// "can't read 'name' of undefined" at import time
exports = {...await import(url)}
} catch {
console.warn(`failed to fetch '${url}' for '${name}'`)
continue
}
let exports: object;
try {
// XXX: pyodide doesn't like Module(), failing with
// "can't read 'name' of undefined" at import time
exports = { ...(await import(url)) };
} catch {
console.warn(`failed to fetch '${url}' for '${name}'`);
continue;
}
pyodide.registerJsModule(name, exports)
pyodide.registerJsModule(name, exports);
}
}
}
}
getSourceFromElement(): string {
return htmlDecode(this.code);
return htmlDecode(this.code);
}
}
}
/** Initialize all elements with py-onClick handlers attributes */
async function initHandlers() {
console.log('Collecting nodes...');
let pyodide = await pyodideReadyPromise;
let matches : NodeListOf<HTMLElement> = document.querySelectorAll('[pys-onClick]');
let output;
let source;
for (var el of matches) {
let handlerCode = el.getAttribute('pys-onClick');
source = `Element("${ el.id }").element.onclick = ${ handlerCode }`;
output = await pyodide.runPythonAsync(source);
console.log('Collecting nodes...');
const pyodide = await pyodideReadyPromise;
let matches: NodeListOf<HTMLElement> = document.querySelectorAll('[pys-onClick]');
let output;
let source;
for (const el of matches) {
const handlerCode = el.getAttribute('pys-onClick');
source = `Element("${el.id}").element.onclick = ${handlerCode}`;
output = await pyodide.runPythonAsync(source);
// TODO: Should we actually map handlers in JS instaed of Python?
// el.onclick = (evt: any) => {
// console.log("click");
// new Promise((resolve, reject) => {
// setTimeout(() => {
// console.log('Inside')
// }, 300);
// }).then(() => {
// console.log("resolved")
// });
// // let handlerCode = el.getAttribute('pys-onClick');
// // pyodide.runPython(handlerCode);
// }
}
handlersCollected = true;
// TODO: Should we actually map handlers in JS instaed of Python?
// el.onclick = (evt: any) => {
// console.log("click");
// new Promise((resolve, reject) => {
// setTimeout(() => {
// console.log('Inside')
// }, 300);
// }).then(() => {
// console.log("resolved")
// });
// // let handlerCode = el.getAttribute('pys-onClick');
// // pyodide.runPython(handlerCode);
// }
}
handlersCollected = true;
matches = document.querySelectorAll('[pys-onKeyDown]');
for (var el of matches) {
let handlerCode = el.getAttribute('pys-onKeyDown');
source = `Element("${ el.id }").element.addEventListener("keydown", ${ handlerCode })`;
output = await pyodide.runPythonAsync(source);
}
matches = document.querySelectorAll('[pys-onKeyDown]');
for (const el of matches) {
const handlerCode = el.getAttribute('pys-onKeyDown');
source = `Element("${el.id}").element.addEventListener("keydown", ${handlerCode})`;
output = await pyodide.runPythonAsync(source);
}
}
/** Mount all elements with attribute py-mount into the Python namespace */
async function mountElements() {
console.log('Collecting nodes to be mounted into python namespace...');
let pyodide = await pyodideReadyPromise;
let matches : NodeListOf<HTMLElement> = document.querySelectorAll('[py-mount]');
let output;
let source = "";
for (var el of matches) {
let mountName = el.getAttribute('py-mount');
if (!mountName){
mountName = el.id.split("-").join("_");
console.log('Collecting nodes to be mounted into python namespace...');
const pyodide = await pyodideReadyPromise;
const matches: NodeListOf<HTMLElement> = document.querySelectorAll('[py-mount]');
let output;
let source = '';
for (const el of matches) {
let mountName = el.getAttribute('py-mount');
if (!mountName) {
mountName = el.id.split('-').join('_');
}
source += `\n${mountName} = Element("${el.id}")`;
}
source += `\n${ mountName } = Element("${ el.id }")`;
}
await pyodide.runPythonAsync(source);
await pyodide.runPythonAsync(source);
}
addInitializer(mountElements);
addPostInitializer(initHandlers);