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

Merge branch 'main' into out-of-box

This commit is contained in:
Fabio Pliger
2022-04-01 10:53:30 -05:00
committed by GitHub
13 changed files with 4986 additions and 25 deletions

4883
pyscriptjs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
"scripts": {
"build": "NODE_ENV=production rollup -c",
"dev": "rollup -c -w",
"start": "sirv public",
"start": "sirv public --no-clear --port 8080",
"validate": "svelte-check"
},
"devDependencies": {

View File

@@ -9,7 +9,7 @@
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="build/bundle.css" />
<script defer src="build/bundle.js"></script>
<script defer src="build/pyscript.js"></script>
</head>
<body>

View File

@@ -9,7 +9,7 @@
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="build/bundle.css" />
<script defer src="build/bundle.js"></script>
<script defer src="build/pyscript.js"></script>
</head>
<body>

View File

@@ -9,7 +9,7 @@
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="build/bundle.css" />
<script defer src="build/bundle.js"></script>
<script defer src="build/pyscript.js"></script>
</head>
<body>

View File

@@ -9,7 +9,7 @@
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="build/bundle.css" />
<script defer src="build/bundle.js"></script>
<script defer src="build/pyscript.js"></script>
</head>
<body>

View File

@@ -40,7 +40,7 @@ export default {
sourcemap: true,
format: "iife",
name: "app",
file: "public/build/bundle.js",
file: "public/build/pyscript.js",
},
plugins: [
svelte({
@@ -54,7 +54,7 @@ export default {
dev: !production,
},
}),
css({ output: "bundle.css" }),
css({ output: "pyscript.css" }),
resolve({
browser: true,
dedupe: ["svelte"],

View File

@@ -4,7 +4,7 @@
import { faPlusCircle } from '@fortawesome/free-solid-svg-icons'
import Tailwind from "./Tailwind.svelte";
import { loadInterpreter } from './interpreter';
import { pyodideLoaded, loadedEnvironments, navBarOpen, componentsNavOpen, mode, scriptsQueue, initializers } from './stores';
import { pyodideLoaded, loadedEnvironments, navBarOpen, componentsNavOpen, mode, scriptsQueue, initializers, postInitializers } from './stores';
import Main from "./Main.svelte";
import Header from "./Header.svelte";
import SideNav from "./SideNav.svelte";
@@ -42,16 +42,21 @@
showNavBar = value;
});
// now we call all initializers before we actually executed all page scripts
for (let initializer of $initializers){
initializer();
}
// now we can actually execute the page scripts if we are in play mode
if ($mode == "play"){
for (let script of $scriptsQueue) {
script.evaluate();
}
scriptsQueue.set([])
scriptsQueue.set([]);
}
// now we call all initializers AFTER we actually executed all page scripts
for (let initializer of $initializers){
// now we call all post initializers AFTER we actually executed all page scripts
for (let initializer of $postInitializers){
initializer();
}
}

View File

@@ -6,7 +6,7 @@ import { keymap, ViewUpdate } from "@codemirror/view";
import { defaultKeymap } from "@codemirror/commands";
import { oneDarkTheme } from "@codemirror/theme-one-dark";
import { pyodideLoaded, loadedEnvironments, componentDetailsNavOpen, currentComponentDetails, mode, addToScriptsQueue, addInitializer } from '../stores';
import { pyodideLoaded, loadedEnvironments, componentDetailsNavOpen, currentComponentDetails, mode, addToScriptsQueue, addInitializer, addPostInitializer } from '../stores';
import { addClasses } from '../utils';
// Premise used to connect to the first available pyodide interpreter
@@ -40,6 +40,10 @@ function createCmdHandler(el){
return toggleCheckbox
}
function htmlDecode(input) {
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
class Script {
source: string;
@@ -214,7 +218,7 @@ export class PyScript extends HTMLElement {
// debugger
try {
// @ts-ignore
let source = this.editor.state.doc.toString();
let source = htmlDecode(this.editor.state.doc.toString());
let output;
if (source.includes("asyncio")){
output = await pyodide.runPythonAsync(source);
@@ -232,6 +236,7 @@ export class PyScript extends HTMLElement {
}
} catch (err) {
this.addToOutput(err);
console.log(err);
}
}
@@ -241,9 +246,8 @@ export class PyScript extends HTMLElement {
}
}
/** Initialize all elements with py-onClick handlers attributes */
async function initHandlers() {
if( handlersCollected == true ) return;
console.log('Collecting nodes...');
let pyodide = await pyodideReadyPromise;
let matches : NodeListOf<HTMLElement> = document.querySelectorAll('[pys-onClick]');
@@ -254,6 +258,7 @@ async function initHandlers() {
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) => {
@@ -276,11 +281,22 @@ async function initHandlers() {
output = await pyodide.runPythonAsync(source);
}
}
addInitializer(initHandlers)
// if( document.readyState === 'loading' ) {
// document.addEventListener( 'DOMContentLoaded', initHandlers );
// }
// else if( document.readyState === 'interactive' || document.readyState === 'complete' ) {
// initHandlers();
// }
/** 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.replace("-", "_");
}
source += `\n${ mountName } = Element("${ el.id }")`;
}
await pyodide.runPythonAsync(source);
}
addPostInitializer(initHandlers);
addInitializer(mountElements);

View File

@@ -102,11 +102,12 @@ let loadInterpreter = async function(): any {
/* @ts-ignore */
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.19.0/full/",
stdout: console.log
stdout: console.log,
stderr: console.log
});
// now that we loaded, add additional convenience fuctions
// pyodide.loadPackage(['matplotlib', 'numpy'])
pyodide.loadPackage(['matplotlib', 'numpy', 'bokeh'])
await pyodide.loadPackage("micropip");
// await pyodide.runPythonAsync(`

View File

@@ -24,9 +24,11 @@ export const currentComponentDetails = writable([]);
export const mode = writable(DEFAULT_MODE)
export const scriptsQueue = writable([])
export const initializers = writable([])
export const postInitializers = writable([])
let scriptsQueue_ = [];
let initializers_ = [];
let postInitializers_ = [];
scriptsQueue.subscribe(value => {
scriptsQueue_ = value;
@@ -40,6 +42,22 @@ scriptsQueue.subscribe(value => {
scriptsQueue_ = value;
});
initializers.subscribe(value => {
initializers_ = value;
});
export const addInitializer = (initializer) => {
console.log("adding initializer", initializer);
initializers.set([...initializers_, initializer]);
console.log("adding initializer", initializer);
};
postInitializers.subscribe(value => {
postInitializers_ = value;
});
export const addPostInitializer = (initializer) => {
console.log("adding post initializer", initializer);
postInitializers.set([...postInitializers_, initializer]);
console.log("adding post initializer", initializer);
};