mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4e25d879e | ||
|
|
c82dbb755e | ||
|
|
1ed77321a5 | ||
|
|
e36a57eb06 | ||
|
|
ee3cd76022 | ||
|
|
eb31e51a45 | ||
|
|
c8c2dd0806 | ||
|
|
e525d54be0 | ||
|
|
7b9f7c13f5 | ||
|
|
7582cbef9c | ||
|
|
b395cde49c | ||
|
|
9f46234f71 | ||
|
|
f4c4edeb29 | ||
|
|
7166c32384 | ||
|
|
ed126889ae | ||
|
|
0d0ea96435 | ||
|
|
fafdf74007 |
17
.github/workflows/prepare-release.yml
vendored
17
.github/workflows/prepare-release.yml
vendored
@@ -19,7 +19,22 @@ jobs:
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
|
||||
- name: Python venv
|
||||
run: python -m venv env
|
||||
|
||||
- name: Activate Python
|
||||
run: source env/bin/activate
|
||||
|
||||
- name: Update pip
|
||||
run: pip install --upgrade pip
|
||||
|
||||
- name: Install PyMinifier
|
||||
run: pip install --ignore-requires-python python-minifier
|
||||
|
||||
- name: Install Setuptools
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v4
|
||||
|
||||
17
.github/workflows/publish-release.yml
vendored
17
.github/workflows/publish-release.yml
vendored
@@ -21,7 +21,22 @@ jobs:
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
|
||||
- name: Python venv
|
||||
run: python -m venv env
|
||||
|
||||
- name: Activate Python
|
||||
run: source env/bin/activate
|
||||
|
||||
- name: Update pip
|
||||
run: pip install --upgrade pip
|
||||
|
||||
- name: Install PyMinifier
|
||||
run: pip install --ignore-requires-python python-minifier
|
||||
|
||||
- name: Install Setuptools
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v4
|
||||
|
||||
17
.github/workflows/publish-snapshot.yml
vendored
17
.github/workflows/publish-snapshot.yml
vendored
@@ -25,7 +25,22 @@ jobs:
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
|
||||
- name: Python venv
|
||||
run: python -m venv env
|
||||
|
||||
- name: Activate Python
|
||||
run: source env/bin/activate
|
||||
|
||||
- name: Update pip
|
||||
run: pip install --upgrade pip
|
||||
|
||||
- name: Install PyMinifier
|
||||
run: pip install --ignore-requires-python python-minifier
|
||||
|
||||
- name: Install Setuptools
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v4
|
||||
|
||||
17
.github/workflows/publish-unstable.yml
vendored
17
.github/workflows/publish-unstable.yml
vendored
@@ -26,7 +26,22 @@ jobs:
|
||||
- name: Install node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18.x
|
||||
node-version: 20.x
|
||||
|
||||
- name: Python venv
|
||||
run: python -m venv env
|
||||
|
||||
- name: Activate Python
|
||||
run: source env/bin/activate
|
||||
|
||||
- name: Update pip
|
||||
run: pip install --upgrade pip
|
||||
|
||||
- name: Install PyMinifier
|
||||
run: pip install --ignore-requires-python python-minifier
|
||||
|
||||
- name: Install Setuptools
|
||||
run: pip install setuptools
|
||||
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v4
|
||||
|
||||
@@ -25,7 +25,7 @@ repos:
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 24.4.2
|
||||
rev: 24.8.0
|
||||
hooks:
|
||||
- id: black
|
||||
exclude: pyscript\.core/src/stdlib/pyscript/__init__\.py
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
.eslintrc.cjs
|
||||
eslint.config.mjs
|
||||
.pytest_cache/
|
||||
node_modules/
|
||||
rollup/
|
||||
test/
|
||||
tests/
|
||||
test-results/
|
||||
src/stdlib/_pyscript
|
||||
src/stdlib/pyscript.py
|
||||
package-lock.json
|
||||
tsconfig.json
|
||||
@@ -12,7 +12,7 @@ Clone this repository then run `npm install` within its folder.
|
||||
|
||||
Use `npm run build` to create all artifacts and _dist_ files.
|
||||
|
||||
Use `npm run server` to test locally, via the `http://localhost:8080/test/` url, smoke tests or to test manually anything you'd like to check.
|
||||
Use `npm run server` to test locally, via the `http://localhost:8080/tests/` url, smoke tests or to test manually anything you'd like to check.
|
||||
|
||||
### Artifacts
|
||||
|
||||
|
||||
741
pyscript.core/package-lock.json
generated
741
pyscript.core/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@pyscript/core",
|
||||
"version": "0.5.1",
|
||||
"version": "0.5.12",
|
||||
"type": "module",
|
||||
"description": "PyScript",
|
||||
"module": "./index.js",
|
||||
@@ -8,6 +8,15 @@
|
||||
"jsdelivr": "./jsdelivr.js",
|
||||
"browser": "./index.js",
|
||||
"main": "./index.js",
|
||||
"files": [
|
||||
"./dist/",
|
||||
"./src/",
|
||||
"./types/",
|
||||
"./index.js",
|
||||
"./jsdelivr.js",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/core.d.ts",
|
||||
@@ -16,19 +25,23 @@
|
||||
"./css": {
|
||||
"import": "./dist/core.css"
|
||||
},
|
||||
"./storage": {
|
||||
"import": "./dist/storage.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"server": "npx static-handler --coi .",
|
||||
"build": "export ESLINT_USE_FLAT_CONFIG=true;npm run build:3rd-party && npm run build:stdlib && npm run build:plugins && npm run build:core && if [ -z \"$NO_MIN\" ]; then eslint src/ && npm run ts && npm run test:mpy; fi",
|
||||
"server": "echo \"➡️ TESTS @ $(tput bold)http://localhost:8080/tests/$(tput sgr0)\"; npx static-handler --coi .",
|
||||
"build": "export ESLINT_USE_FLAT_CONFIG=true;npm run build:3rd-party && npm run build:stdlib && npm run build:plugins && npm run build:core && npm run build:tests-index && if [ -z \"$NO_MIN\" ]; then eslint src/ && npm run ts && npm run test:integration; fi",
|
||||
"build:core": "rm -rf dist && rollup --config rollup/core.config.js && cp src/3rd-party/*.css dist/",
|
||||
"build:flatted": "node rollup/flatted.cjs",
|
||||
"build:plugins": "node rollup/plugins.cjs",
|
||||
"build:stdlib": "node rollup/stdlib.cjs",
|
||||
"build:3rd-party": "node rollup/3rd-party.cjs",
|
||||
"build:tests-index": "node rollup/build_test_index.cjs",
|
||||
"clean:3rd-party": "rm src/3rd-party/*.js && rm src/3rd-party/*.css",
|
||||
"test:mpy": "static-handler --coi . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test --fully-parallel test/mpy.spec.js || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE",
|
||||
"test:ws": "bun test/ws/index.js & playwright test test/ws.spec.js",
|
||||
"test:integration": "static-handler --coi . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test --fully-parallel tests/integration.spec.js || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE",
|
||||
"test:ws": "bun tests/ws/index.js & playwright test tests/ws.spec.js",
|
||||
"dev": "node dev.cjs",
|
||||
"release": "npm run build && npm run zip",
|
||||
"size": "echo -e \"\\033[1mdist/*.js file size\\033[0m\"; for js in $(ls dist/*.js); do cat $js | brotli > ._; echo -e \"\\033[2m$js:\\033[0m $(du -h --apparent-size ._ | sed -e 's/[[:space:]]*._//')\"; rm ._; done",
|
||||
@@ -43,35 +56,37 @@
|
||||
"license": "APACHE-2.0",
|
||||
"dependencies": {
|
||||
"@ungap/with-resolvers": "^0.1.0",
|
||||
"@webreflection/idb-map": "^0.3.1",
|
||||
"basic-devtools": "^0.1.6",
|
||||
"polyscript": "^0.14.4",
|
||||
"polyscript": "^0.15.6",
|
||||
"sabayon": "^0.5.2",
|
||||
"sticky-module": "^0.1.1",
|
||||
"to-json-callback": "^0.1.1",
|
||||
"type-checked-collections": "^0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@codemirror/commands": "^6.6.0",
|
||||
"@codemirror/commands": "^6.6.1",
|
||||
"@codemirror/lang-python": "^6.1.6",
|
||||
"@codemirror/language": "^6.10.2",
|
||||
"@codemirror/state": "^6.4.1",
|
||||
"@codemirror/view": "^6.29.1",
|
||||
"@playwright/test": "^1.45.3",
|
||||
"@codemirror/view": "^6.33.0",
|
||||
"@playwright/test": "1.45.3",
|
||||
"@rollup/plugin-commonjs": "^26.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@webreflection/toml-j0.4": "^1.1.3",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/addon-web-links": "^0.11.0",
|
||||
"bun": "^1.1.21",
|
||||
"chokidar": "^3.6.0",
|
||||
"bun": "^1.1.27",
|
||||
"chokidar": "^4.0.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"eslint": "^9.8.0",
|
||||
"eslint": "^9.10.0",
|
||||
"flatted": "^3.3.1",
|
||||
"rollup": "^4.19.1",
|
||||
"rollup": "^4.21.3",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"static-handler": "^0.4.3",
|
||||
"typescript": "^5.5.4",
|
||||
"static-handler": "^0.5.3",
|
||||
"typescript": "^5.6.2",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-readline": "^1.1.1"
|
||||
},
|
||||
|
||||
73
pyscript.core/rollup/build_test_index.cjs
Normal file
73
pyscript.core/rollup/build_test_index.cjs
Normal file
@@ -0,0 +1,73 @@
|
||||
const { join } = require("node:path");
|
||||
const { lstatSync, readdirSync, writeFileSync } = require("node:fs");
|
||||
|
||||
// folders to not consider while crawling
|
||||
const EXCLUDE_DIR = new Set(["ws"]);
|
||||
|
||||
const TEST_DIR = join(__dirname, "..", "tests");
|
||||
|
||||
const TEST_INDEX = join(TEST_DIR, "index.html");
|
||||
|
||||
const crawl = (path, tree = {}) => {
|
||||
for (const file of readdirSync(path)) {
|
||||
const current = join(path, file);
|
||||
if (current === TEST_INDEX) continue;
|
||||
if (lstatSync(current).isDirectory()) {
|
||||
if (EXCLUDE_DIR.has(file)) continue;
|
||||
const sub = {};
|
||||
tree[file] = sub;
|
||||
crawl(current, sub);
|
||||
if (!Reflect.ownKeys(sub).length) {
|
||||
delete tree[file];
|
||||
}
|
||||
} else if (file.endsWith(".html")) {
|
||||
const name = file === "index.html" ? "." : file.slice(0, -5);
|
||||
tree[name] = current.replace(TEST_DIR, "");
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
};
|
||||
|
||||
const createList = (tree) => {
|
||||
const ul = ["<ul>"];
|
||||
for (const [key, value] of Object.entries(tree)) {
|
||||
ul.push("<li>");
|
||||
if (typeof value === "string") {
|
||||
ul.push(`<a href=".${value}">${key}<small>.html</small></a>`);
|
||||
} else {
|
||||
if ("." in value) {
|
||||
ul.push(`<strong><a href=".${value["."]}">${key}</a></strong>`);
|
||||
delete value["."];
|
||||
} else {
|
||||
ul.push(`<strong><span>${key}</span></strong>`);
|
||||
}
|
||||
if (Reflect.ownKeys(value).length) ul.push(createList(value));
|
||||
}
|
||||
ul.push("</li>");
|
||||
}
|
||||
ul.push("</ul>");
|
||||
return ul.join("");
|
||||
};
|
||||
|
||||
writeFileSync(
|
||||
TEST_INDEX,
|
||||
`<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript tests</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; }
|
||||
a {
|
||||
display: block;
|
||||
transition: opacity .3s;
|
||||
}
|
||||
a, span { opacity: .7; }
|
||||
a:hover { opacity: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body>${createList(crawl(TEST_DIR))}</body>
|
||||
</html>
|
||||
`,
|
||||
);
|
||||
@@ -40,4 +40,17 @@ export default [
|
||||
warn(warning);
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "./src/storage.js",
|
||||
plugins: plugins.concat(
|
||||
process.env.NO_MIN
|
||||
? [nodeResolve(), commonjs()]
|
||||
: [nodeResolve(), commonjs(), terser()],
|
||||
),
|
||||
output: {
|
||||
esModule: true,
|
||||
dir: "./dist",
|
||||
sourcemap: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -4,13 +4,27 @@ const {
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} = require("node:fs");
|
||||
|
||||
const { spawnSync } = require("node:child_process");
|
||||
|
||||
const { join } = require("node:path");
|
||||
|
||||
const crawl = (path, json) => {
|
||||
for (const file of readdirSync(path)) {
|
||||
const full = join(path, file);
|
||||
if (/\.py$/.test(file)) json[file] = readFileSync(full).toString();
|
||||
else if (statSync(full).isDirectory() && !file.endsWith("_"))
|
||||
if (/\.py$/.test(file)) {
|
||||
if (process.env.NO_MIN) json[file] = readFileSync(full).toString();
|
||||
else {
|
||||
const {
|
||||
output: [error, result],
|
||||
} = spawnSync("pyminify", [
|
||||
"--remove-literal-statements",
|
||||
full,
|
||||
]);
|
||||
if (error) process.exit(1);
|
||||
json[file] = result.toString();
|
||||
}
|
||||
} else if (statSync(full).isDirectory() && !file.endsWith("_"))
|
||||
crawl(full, (json[file] = {}));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
define,
|
||||
defineProperty,
|
||||
dispatch,
|
||||
isSync,
|
||||
queryTarget,
|
||||
unescape,
|
||||
whenDefined,
|
||||
@@ -202,15 +203,13 @@ for (const [TYPE, interpreter] of TYPES) {
|
||||
}
|
||||
|
||||
if (isScript(element)) {
|
||||
const {
|
||||
attributes: { async: isAsync, target },
|
||||
} = element;
|
||||
const hasTarget = !!target?.value;
|
||||
const show = hasTarget
|
||||
? queryTarget(element, target.value)
|
||||
const isAsync = !isSync(element);
|
||||
const target = element.getAttribute("target");
|
||||
const show = target
|
||||
? queryTarget(element, target)
|
||||
: document.createElement("script-py");
|
||||
|
||||
if (!hasTarget) {
|
||||
if (!target) {
|
||||
const { head, body } = document;
|
||||
if (head.contains(element)) body.append(show);
|
||||
else element.after(show);
|
||||
@@ -331,7 +330,7 @@ for (const [TYPE, interpreter] of TYPES) {
|
||||
async connectedCallback() {
|
||||
if (!this.executed) {
|
||||
this.executed = true;
|
||||
const isAsync = this.hasAttribute("async");
|
||||
const isAsync = !isSync(this);
|
||||
const { io, run, runAsync } = await this._wrap
|
||||
.promise;
|
||||
this.srcCode = await fetchSource(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// PyScript py-editor plugin
|
||||
import { Hook, XWorker, dedent, defineProperties } from "polyscript/exports";
|
||||
import { TYPES, offline_interpreter, relative_url, stdlib } from "../core.js";
|
||||
import { notify } from "./error.js";
|
||||
|
||||
const RUN_BUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
|
||||
|
||||
@@ -23,6 +24,11 @@ const hooks = {
|
||||
},
|
||||
};
|
||||
|
||||
const validate = (config, result) => {
|
||||
if (typeof result === "boolean") throw `Invalid source: ${config}`;
|
||||
return result;
|
||||
};
|
||||
|
||||
async function execute({ currentTarget }) {
|
||||
const { env, pySrc, outDiv } = this;
|
||||
const hasRunButton = !!currentTarget;
|
||||
@@ -40,20 +46,31 @@ async function execute({ currentTarget }) {
|
||||
};
|
||||
const { config } = this;
|
||||
if (config) {
|
||||
details.configURL = relative_url(config);
|
||||
if (config.endsWith(".toml")) {
|
||||
const [{ parse }, toml] = await Promise.all([
|
||||
import(/* webpackIgnore: true */ "../3rd-party/toml.js"),
|
||||
fetch(config).then((r) => r.text()),
|
||||
]);
|
||||
details.config = parse(toml);
|
||||
} else if (config.endsWith(".json")) {
|
||||
details.config = await fetch(config).then((r) => r.json());
|
||||
} else {
|
||||
details.configURL = relative_url("./config.txt");
|
||||
details.config = JSON.parse(config);
|
||||
// verify that config can be parsed and used
|
||||
try {
|
||||
details.configURL = relative_url(config);
|
||||
if (config.endsWith(".toml")) {
|
||||
const [{ parse }, toml] = await Promise.all([
|
||||
import(
|
||||
/* webpackIgnore: true */ "../3rd-party/toml.js"
|
||||
),
|
||||
fetch(config).then((r) => r.ok && r.text()),
|
||||
]);
|
||||
details.config = parse(validate(config, toml));
|
||||
} else if (config.endsWith(".json")) {
|
||||
const json = await fetch(config).then(
|
||||
(r) => r.ok && r.json(),
|
||||
);
|
||||
details.config = validate(config, json);
|
||||
} else {
|
||||
details.configURL = relative_url("./config.txt");
|
||||
details.config = JSON.parse(config);
|
||||
}
|
||||
details.version = offline_interpreter(details.config);
|
||||
} catch (error) {
|
||||
notify(error);
|
||||
return;
|
||||
}
|
||||
details.version = offline_interpreter(details.config);
|
||||
} else {
|
||||
details.config = {};
|
||||
}
|
||||
@@ -74,9 +91,12 @@ async function execute({ currentTarget }) {
|
||||
return envs.get(env).then((xworker) => {
|
||||
xworker.onerror = ({ error }) => {
|
||||
if (hasRunButton) {
|
||||
outDiv.innerHTML += `<span style='color:red'>${
|
||||
error.message || error
|
||||
}</span>\n`;
|
||||
outDiv.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
`<span style='color:red'>${
|
||||
error.message || error
|
||||
}</span>\n`,
|
||||
);
|
||||
}
|
||||
console.error(error);
|
||||
};
|
||||
@@ -87,10 +107,17 @@ async function execute({ currentTarget }) {
|
||||
const { sync } = xworker;
|
||||
sync.write = (str) => {
|
||||
if (hasRunButton) outDiv.innerText += `${str}\n`;
|
||||
else console.log(str);
|
||||
};
|
||||
sync.writeErr = (str) => {
|
||||
if (hasRunButton) {
|
||||
outDiv.innerHTML += `<span style='color:red'>${str}</span>\n`;
|
||||
outDiv.insertAdjacentHTML(
|
||||
"beforeend",
|
||||
`<span style='color:red'>${str}</span>\n`,
|
||||
);
|
||||
} else {
|
||||
notify(str);
|
||||
console.error(str);
|
||||
}
|
||||
};
|
||||
sync.runAsync(pySrc).then(enable, enable);
|
||||
@@ -187,9 +214,22 @@ const init = async (script, type, interpreter) => {
|
||||
|
||||
configs.set(env, hasConfig);
|
||||
|
||||
let source = script.src
|
||||
? await fetch(script.src).then((b) => b.text())
|
||||
: script.textContent;
|
||||
let source = script.textContent;
|
||||
|
||||
// verify the src points to a valid file that can be parsed
|
||||
const { src } = script;
|
||||
if (src) {
|
||||
try {
|
||||
source = validate(
|
||||
src,
|
||||
await fetch(src).then((b) => b.ok && b.text()),
|
||||
);
|
||||
} catch (error) {
|
||||
notify(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const context = {
|
||||
// allow the listener to be overridden at distance
|
||||
handleEvent: execute,
|
||||
@@ -268,14 +308,14 @@ const init = async (script, type, interpreter) => {
|
||||
},
|
||||
});
|
||||
|
||||
const notify = () => {
|
||||
const notifyEditor = () => {
|
||||
const event = new Event(`${type}-editor`, { bubbles: true });
|
||||
script.dispatchEvent(event);
|
||||
};
|
||||
|
||||
if (isSetup) {
|
||||
await context.handleEvent({ currentTarget: null });
|
||||
notify();
|
||||
notifyEditor();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -334,7 +374,7 @@ const init = async (script, type, interpreter) => {
|
||||
});
|
||||
|
||||
editor.focus();
|
||||
notify();
|
||||
notifyEditor();
|
||||
};
|
||||
|
||||
// avoid too greedy MutationObserver operations at distance
|
||||
|
||||
@@ -41,8 +41,16 @@ def when(event_type=None, selector=None):
|
||||
# Function doesn't receive events
|
||||
if not sig.parameters:
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
func()
|
||||
# Function is async: must be awaited
|
||||
if inspect.iscoroutinefunction(func):
|
||||
|
||||
async def wrapper(*args, **kwargs):
|
||||
await func()
|
||||
|
||||
else:
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
func()
|
||||
|
||||
else:
|
||||
wrapper = func
|
||||
|
||||
@@ -421,7 +421,7 @@ class ContainerElement(Element):
|
||||
self.append(child)
|
||||
|
||||
else:
|
||||
self.innerHTML += child
|
||||
self._dom_element.insertAdjacentHTML("beforeend", child)
|
||||
|
||||
def __iter__(self):
|
||||
yield from self.children
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import js
|
||||
from pyscript.ffi import create_proxy
|
||||
from pyscript.util import as_bytearray
|
||||
|
||||
code = "code"
|
||||
@@ -38,7 +39,8 @@ class WebSocket(object):
|
||||
|
||||
for t in ["onclose", "onerror", "onmessage", "onopen"]:
|
||||
if t in kw:
|
||||
socket[t] = kw[t]
|
||||
# Pyodide fails at setting socket[t] directly
|
||||
setattr(socket, t, create_proxy(kw[t]))
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return getattr(self._ws, attr)
|
||||
|
||||
72
pyscript.core/src/storage.js
Normal file
72
pyscript.core/src/storage.js
Normal file
@@ -0,0 +1,72 @@
|
||||
import { ArrayBuffer, TypedArray } from "sabayon/shared";
|
||||
import IDBMapSync from "@webreflection/idb-map/sync";
|
||||
import { parse, stringify } from "flatted";
|
||||
|
||||
const to_idb = (value) => {
|
||||
if (value == null) return stringify(["null", 0]);
|
||||
/* eslint-disable no-fallthrough */
|
||||
switch (typeof value) {
|
||||
case "object": {
|
||||
if (value instanceof TypedArray)
|
||||
return stringify(["memoryview", [...value]]);
|
||||
if (value instanceof ArrayBuffer)
|
||||
return stringify(["bytearray", [...new Uint8Array(value)]]);
|
||||
}
|
||||
case "string":
|
||||
case "number":
|
||||
case "boolean":
|
||||
return stringify(["generic", value]);
|
||||
default:
|
||||
throw new TypeError(`Unexpected value: ${String(value)}`);
|
||||
}
|
||||
};
|
||||
|
||||
const from_idb = (value) => {
|
||||
const [kind, result] = parse(value);
|
||||
if (kind === "null") return null;
|
||||
if (kind === "generic") return result;
|
||||
if (kind === "bytearray") return new Uint8Array(value).buffer;
|
||||
if (kind === "memoryview") return new Uint8Array(value);
|
||||
return value;
|
||||
};
|
||||
|
||||
// this export simulate pyscript.storage exposed in the Python world
|
||||
export const storage = async (name) => {
|
||||
if (!name) throw new SyntaxError("The storage name must be defined");
|
||||
|
||||
const store = new IDBMapSync(`@pyscript/${name}`);
|
||||
const map = new Map();
|
||||
await store.sync();
|
||||
for (const [k, v] of store.entries()) map.set(k, from_idb(v));
|
||||
|
||||
const clear = () => {
|
||||
map.clear();
|
||||
store.clear();
|
||||
};
|
||||
|
||||
const sync = async () => {
|
||||
await store.sync();
|
||||
};
|
||||
|
||||
return new Proxy(map, {
|
||||
ownKeys: (map) => [...map.keys()],
|
||||
has: (map, name) => map.has(name),
|
||||
get: (map, name) => {
|
||||
if (name === "clear") return clear;
|
||||
if (name === "sync") return sync;
|
||||
return map.get(name);
|
||||
},
|
||||
set: (map, name, value) => {
|
||||
map.set(name, value);
|
||||
store.set(name, to_idb(value));
|
||||
return true;
|
||||
},
|
||||
deleteProperty: (map, name) => {
|
||||
if (map.has(name)) {
|
||||
map.delete(name);
|
||||
store.delete(name);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<py-script async>
|
||||
import asyncio
|
||||
print('foo')
|
||||
await asyncio.sleep(1)
|
||||
print('bar')
|
||||
</py-script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,39 +0,0 @@
|
||||
// PyScript Error Plugin
|
||||
import { hooks } from '@pyscript/core';
|
||||
|
||||
hooks.onBeforeRun.add(function override(pyScript) {
|
||||
// be sure this override happens only once
|
||||
hooks.onBeforeRun.delete(override);
|
||||
|
||||
// trap generic `stderr` to propagate to it regardless
|
||||
const { stderr } = pyScript.io;
|
||||
|
||||
// override it with our own logic
|
||||
pyScript.io.stderr = (...args) => {
|
||||
// grab the message of the first argument (Error)
|
||||
const [ { message } ] = args;
|
||||
// show it
|
||||
notify(message);
|
||||
// still let other plugins or PyScript itself do the rest
|
||||
return stderr(...args);
|
||||
};
|
||||
});
|
||||
|
||||
// Error hook utilities
|
||||
|
||||
// Custom function to show notifications
|
||||
function notify(message) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = message;
|
||||
div.style.cssText = `
|
||||
border: 1px solid red;
|
||||
background: #ffdddd;
|
||||
color: black;
|
||||
font-family: courier, monospace;
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
padding: 8px;
|
||||
margin-top: 8px;
|
||||
`;
|
||||
document.body.append(div);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyDom Example</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" src="pydom.py"></script>
|
||||
|
||||
<div id="system-info"></div>
|
||||
|
||||
<button id="just-a-button">Click For Time</button>
|
||||
<button id="color-button">Click For Color</button>
|
||||
<button id="color-reset-button">Reset Color</button>
|
||||
|
||||
<div id="result"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +0,0 @@
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
from datetime import datetime as dt
|
||||
|
||||
from pyscript import display, when
|
||||
from pyscript.web import dom
|
||||
|
||||
display(sys.version, target="system-info")
|
||||
|
||||
|
||||
@when("click", "#just-a-button")
|
||||
def on_click():
|
||||
try:
|
||||
timenow = dt.now()
|
||||
except NotImplementedError:
|
||||
# In this case we assume it's not implemented because we are using MycroPython
|
||||
tnow = time.localtime()
|
||||
tstr = "{:02d}/{:02d}/{:04d} {:02d}:{:02d}:{:02d}"
|
||||
timenow = tstr.format(tnow[2], tnow[1], tnow[0], *tnow[2:])
|
||||
|
||||
display(f"Hello from PyScript, time is: {timenow}", append=False, target="#result")
|
||||
|
||||
|
||||
@when("click", "#color-button")
|
||||
def on_color_click(event):
|
||||
btn = dom["#result"]
|
||||
btn.style["background-color"] = f"#{random.randrange(0x1000000):06x}"
|
||||
|
||||
|
||||
@when("click", "#color-reset-button")
|
||||
def reset_color(*args, **kwargs):
|
||||
dom["#result"].style["background-color"] = "white"
|
||||
@@ -1,21 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyDom Example (MicroPython)</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" src="pydom.py"></script>
|
||||
|
||||
<div id="system-info"></div>
|
||||
|
||||
<button id="just-a-button">Click For Time</button>
|
||||
<button id="color-button">Click For Color</button>
|
||||
<button id="color-reset-button">Reset Color</button>
|
||||
|
||||
<div id="result"></div>
|
||||
</body>
|
||||
</html>
|
||||
18
pyscript.core/tests/index.html
Normal file
18
pyscript.core/tests/index.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript tests</title>
|
||||
<style>
|
||||
body { font-family: sans-serif; }
|
||||
a {
|
||||
display: block;
|
||||
transition: opacity .3s;
|
||||
}
|
||||
a, span { opacity: .7; }
|
||||
a:hover { opacity: 1; }
|
||||
</style>
|
||||
</head>
|
||||
<body><ul><li><strong><a href="./config/index.html">config</a></strong><ul><li><a href="./config/ambiguous-config.html">ambiguous-config<small>.html</small></a></li><li><a href="./config/same-config.html">same-config<small>.html</small></a></li><li><a href="./config/too-many-config.html">too-many-config<small>.html</small></a></li><li><a href="./config/too-many-py-config.html">too-many-py-config<small>.html</small></a></li></ul></li><li><strong><a href="./issue-7015/index.html">issue-7015</a></strong></li><li><strong><span>js-integration</span></strong><ul><li><a href="./js-integration/async-listener.html">async-listener<small>.html</small></a></li><li><a href="./js-integration/config-url.html">config-url<small>.html</small></a></li><li><strong><a href="./js-integration/fetch/index.html">fetch</a></strong></li><li><a href="./js-integration/ffi.html">ffi<small>.html</small></a></li><li><a href="./js-integration/hooks.html">hooks<small>.html</small></a></li><li><strong><a href="./js-integration/issue-2093/index.html">issue-2093</a></strong></li><li><a href="./js-integration/js-storage.html">js-storage<small>.html</small></a></li><li><a href="./js-integration/js_modules.html">js_modules<small>.html</small></a></li><li><strong><a href="./js-integration/loader/index.html">loader</a></strong></li><li><a href="./js-integration/mpy.html">mpy<small>.html</small></a></li><li><a href="./js-integration/py-terminal-main.html">py-terminal-main<small>.html</small></a></li><li><a href="./js-integration/py-terminal-worker.html">py-terminal-worker<small>.html</small></a></li><li><a href="./js-integration/py-terminal.html">py-terminal<small>.html</small></a></li><li><a href="./js-integration/py-terminals.html">py-terminals<small>.html</small></a></li><li><a href="./js-integration/storage.html">storage<small>.html</small></a></li><li><strong><a href="./js-integration/workers/index.html">workers</a></strong><ul><li><a href="./js-integration/workers/named.html">named<small>.html</small></a></li></ul></li></ul></li><li><strong><a href="./manual/index.html">manual</a></strong><ul><li><a href="./manual/all-done.html">all-done<small>.html</small></a></li><li><a href="./manual/async.html">async<small>.html</small></a></li><li><a href="./manual/camera.html">camera<small>.html</small></a></li><li><a href="./manual/click.html">click<small>.html</small></a></li><li><a href="./manual/code-a-part.html">code-a-part<small>.html</small></a></li><li><a href="./manual/combo.html">combo<small>.html</small></a></li><li><a href="./manual/config.html">config<small>.html</small></a></li><li><a href="./manual/create-element.html">create-element<small>.html</small></a></li><li><a href="./manual/dialog.html">dialog<small>.html</small></a></li><li><a href="./manual/display.html">display<small>.html</small></a></li><li><a href="./manual/error.html">error<small>.html</small></a></li><li><a href="./manual/html-decode.html">html-decode<small>.html</small></a></li><li><a href="./manual/input.html">input<small>.html</small></a></li><li><a href="./manual/interpreter.html">interpreter<small>.html</small></a></li><li><a href="./manual/multi.html">multi<small>.html</small></a></li><li><a href="./manual/multiple-editors.html">multiple-editors<small>.html</small></a></li><li><a href="./manual/no-error.html">no-error<small>.html</small></a></li><li><a href="./manual/py-editor-failure.html">py-editor-failure<small>.html</small></a></li><li><a href="./manual/py-editor.html">py-editor<small>.html</small></a></li><li><a href="./manual/py_modules.html">py_modules<small>.html</small></a></li><li><a href="./manual/split-config.html">split-config<small>.html</small></a></li><li><a href="./manual/target.html">target<small>.html</small></a></li><li><a href="./manual/test_display_HTML.html">test_display_HTML<small>.html</small></a></li><li><a href="./manual/test_when.html">test_when<small>.html</small></a></li><li><a href="./manual/worker.html">worker<small>.html</small></a></li></ul></li><li><strong><a href="./no_sab/index.html">no_sab</a></strong></li><li><strong><a href="./piratical/index.html">piratical</a></strong></li><li><strong><a href="./py-editor/index.html">py-editor</a></strong><ul><li><a href="./py-editor/issue-2056.html">issue-2056<small>.html</small></a></li><li><a href="./py-editor/service-worker.html">service-worker<small>.html</small></a></li></ul></li><li><strong><a href="./py-terminals/index.html">py-terminals</a></strong><ul><li><a href="./py-terminals/no-repl.html">no-repl<small>.html</small></a></li><li><a href="./py-terminals/repl.html">repl<small>.html</small></a></li></ul></li><li><strong><a href="./pyscript_dom/index.html">pyscript_dom</a></strong></li><li><strong><a href="./service-worker/index.html">service-worker</a></strong></li><li><strong><a href="./ui/index.html">ui</a></strong><ul><li><a href="./ui/gallery.html">gallery<small>.html</small></a></li></ul></li></ul></body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
test('MicroPython display', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/mpy.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/mpy.html');
|
||||
await page.waitForSelector('html.done.worker');
|
||||
const body = await page.evaluate(() => document.body.innerText);
|
||||
await expect(body.trim()).toBe([
|
||||
@@ -18,7 +18,7 @@ test('MicroPython hooks', async ({ page }) => {
|
||||
if (!text.startsWith('['))
|
||||
logs.push(text);
|
||||
});
|
||||
await page.goto('http://localhost:8080/test/hooks.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/hooks.html');
|
||||
await page.waitForSelector('html.done.worker');
|
||||
await expect(logs.join('\n')).toBe([
|
||||
'main onReady',
|
||||
@@ -43,7 +43,7 @@ test('MicroPython + Pyodide js_modules', async ({ page }) => {
|
||||
if (!text.startsWith('['))
|
||||
logs.push(text);
|
||||
});
|
||||
await page.goto('http://localhost:8080/test/js_modules.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/js_modules.html');
|
||||
await page.waitForSelector('html.done');
|
||||
await expect(logs.length).toBe(6);
|
||||
await expect(logs[0]).toBe(logs[1]);
|
||||
@@ -53,48 +53,64 @@ test('MicroPython + Pyodide js_modules', async ({ page }) => {
|
||||
});
|
||||
|
||||
test('MicroPython + configURL', async ({ page }) => {
|
||||
const logs = [];
|
||||
page.on('console', msg => {
|
||||
const text = msg.text();
|
||||
if (!text.startsWith('['))
|
||||
logs.push(text);
|
||||
});
|
||||
await page.goto('http://localhost:8080/test/config-url.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/config-url.html');
|
||||
await page.waitForSelector('html.main.worker');
|
||||
});
|
||||
|
||||
test('Pyodide + terminal on Main', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/py-terminal-main.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/py-terminal-main.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
});
|
||||
|
||||
|
||||
test('Pyodide + terminal on Worker', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/py-terminal-worker.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/py-terminal-worker.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
});
|
||||
|
||||
test('Pyodide + multiple terminals via Worker', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/py-terminals.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/py-terminals.html');
|
||||
await page.waitForSelector('html.first.second');
|
||||
});
|
||||
|
||||
test('MicroPython + Pyodide fetch', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/fetch.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/fetch/index.html');
|
||||
await page.waitForSelector('html.mpy.py');
|
||||
});
|
||||
|
||||
test('MicroPython + Pyodide ffi', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/ffi.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/ffi.html');
|
||||
await page.waitForSelector('html.mpy.py');
|
||||
});
|
||||
|
||||
test('MicroPython + Storage', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/storage.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/storage.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
});
|
||||
|
||||
test('MicroPython + JS Storage', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/tests/js-integration/js-storage.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
});
|
||||
|
||||
test('MicroPython + workers', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/workers/index.html');
|
||||
await page.goto('http://localhost:8080/tests/js-integration/workers/index.html');
|
||||
await page.waitForSelector('html.mpy.py');
|
||||
});
|
||||
|
||||
test('MicroPython Editor setup error', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/tests/js-integration/issue-2093/index.html');
|
||||
await page.waitForSelector('html.errored');
|
||||
});
|
||||
|
||||
test('MicroPython async @when listener', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/tests/js-integration/async-listener.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
});
|
||||
|
||||
test('Pyodide loader', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/tests/js-integration/loader/index.html');
|
||||
await page.waitForSelector('html.ok');
|
||||
const body = await page.evaluate(() => document.body.textContent);
|
||||
await expect(body.includes('Loaded Pyodide')).toBe(true);
|
||||
});
|
||||
@@ -17,7 +17,7 @@ from playwright.sync_api import Error as PlaywrightError
|
||||
|
||||
ROOT = py.path.local(__file__).dirpath("..", "..", "..")
|
||||
BUILD = ROOT.join("pyscript.core").join("dist")
|
||||
TEST = ROOT.join("pyscript.core").join("test")
|
||||
TEST = ROOT.join("pyscript.core").join("tests")
|
||||
|
||||
|
||||
def params_with_marks(params):
|
||||
@@ -212,7 +212,7 @@ class PyScriptTest:
|
||||
tmpdir.join("dist").mksymlinkto(BUILD)
|
||||
# create a symlink to TEST inside tmpdir so we can run tests in that
|
||||
# manual test folder
|
||||
tmpdir.join("test").mksymlinkto(TEST)
|
||||
tmpdir.join("tests").mksymlinkto(TEST)
|
||||
|
||||
# create a symlink to the favicon, so that we can use it in the HTML
|
||||
self.tmpdir.chdir()
|
||||
|
||||
@@ -97,7 +97,7 @@ class TestBasic(PyScriptTest):
|
||||
def test_input_exception(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py">
|
||||
<script type="py" async="false">
|
||||
input("what's your name?")
|
||||
</script>
|
||||
"""
|
||||
|
||||
@@ -43,12 +43,12 @@ class TestDisplay(PyScriptTest):
|
||||
def test_consecutive_display(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py">
|
||||
<script type="py" async="false">
|
||||
from pyscript import display
|
||||
display('hello 1')
|
||||
</script>
|
||||
<p>hello 2</p>
|
||||
<script type="py">
|
||||
<script type="py" async="false">
|
||||
from pyscript import display
|
||||
display('hello 3')
|
||||
</script>
|
||||
@@ -177,16 +177,16 @@ class TestDisplay(PyScriptTest):
|
||||
def test_consecutive_display_target(self):
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py" id="first">
|
||||
<script type="py" id="first" async="false">
|
||||
from pyscript import display
|
||||
display('hello 1')
|
||||
</script>
|
||||
<p>hello in between 1 and 2</p>
|
||||
<script type="py" id="second">
|
||||
<script type="py" id="second" async="false">
|
||||
from pyscript import display
|
||||
display('hello 2', target="second")
|
||||
</script>
|
||||
<script type="py" id="third">
|
||||
<script type="py" id="third" async="false">
|
||||
from pyscript import display
|
||||
display('hello 3')
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,6 @@ from .support import PyScriptTest, with_execution_thread
|
||||
class TestSmokeTests(PyScriptTest):
|
||||
"""
|
||||
Each example requires the same three tests:
|
||||
|
||||
- Test that the initial markup loads properly (currently done by
|
||||
testing the <title> tag's content)
|
||||
- Testing that pyscript is loading properly
|
||||
@@ -14,7 +13,7 @@ class TestSmokeTests(PyScriptTest):
|
||||
|
||||
def test_pydom(self):
|
||||
# Test the full pydom test suite by running it in the browser
|
||||
self.goto("test/pyscript_dom/index.html?-v&-s")
|
||||
self.goto("tests/pyscript_dom/index.html?-v&-s")
|
||||
assert self.page.title() == "PyDom Test Suite"
|
||||
|
||||
# wait for the test suite to finish
|
||||
|
||||
24
pyscript.core/tests/js-integration/async-listener.html
Normal file
24
pyscript.core/tests/js-integration/async-listener.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy">
|
||||
from pyscript import window, document, fetch, when
|
||||
|
||||
@when('click', '#click')
|
||||
async def click(event):
|
||||
text = await fetch(window.location.href).text()
|
||||
document.getElementById('output').append(text)
|
||||
document.documentElement.classList.add('ok')
|
||||
|
||||
document.getElementById('click').click()
|
||||
</script>
|
||||
<button id="click">click</button>
|
||||
<pre id="output"></pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next Plugin</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<mpy-config src="config-url/config.json"></mpy-config>
|
||||
<script type="mpy">
|
||||
from pyscript import config
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../../dist/core.css">
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
@@ -18,7 +18,7 @@
|
||||
document.createElement('script'),
|
||||
{
|
||||
type: 'module',
|
||||
src: '../dist/core.js'
|
||||
src: '../../../dist/core.js'
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript FFI</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy">
|
||||
@@ -4,13 +4,13 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next Plugin Bug?</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module">
|
||||
addEventListener('mpy:done', () => {
|
||||
document.documentElement.classList.add('done');
|
||||
});
|
||||
|
||||
import { hooks } from "../dist/core.js";
|
||||
import { hooks } from "../../dist/core.js";
|
||||
|
||||
// Main
|
||||
hooks.main.onReady.add((wrap, element) => {
|
||||
@@ -48,12 +48,12 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" worker>
|
||||
<script type="mpy" async="false" worker>
|
||||
from pyscript import document
|
||||
print("actual code in worker")
|
||||
document.documentElement.classList.add('worker')
|
||||
</script>
|
||||
<script type="mpy">
|
||||
<script type="mpy" async="false">
|
||||
print("actual code in main")
|
||||
</script>
|
||||
</body>
|
||||
6
pyscript.core/tests/js-integration/issue-2093/error.js
Normal file
6
pyscript.core/tests/js-integration/issue-2093/error.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const { error } = console;
|
||||
|
||||
console.error = (...args) => {
|
||||
error(...args);
|
||||
document.documentElement.classList.add('errored');
|
||||
};
|
||||
16
pyscript.core/tests/js-integration/issue-2093/index.html
Normal file
16
pyscript.core/tests/js-integration/issue-2093/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="../../../dist/core.css">
|
||||
<script type="module" src="./error.js"></script>
|
||||
<script type="module" src="../../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy-editor" setup>
|
||||
print("Hello Editor")
|
||||
raise Exception("failure")
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
28
pyscript.core/tests/js-integration/js-storage.html
Normal file
28
pyscript.core/tests/js-integration/js-storage.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module">
|
||||
import { storage } from '../../dist/storage.js';
|
||||
|
||||
const store = await storage('js-storage');
|
||||
store.test = [1, 2, 3].map(String);
|
||||
await store.sync();
|
||||
|
||||
// be sure the store is not empty before bootstrap
|
||||
import('../../dist/core.js');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy">
|
||||
from pyscript import storage, document
|
||||
|
||||
store = await storage("js-storage")
|
||||
|
||||
if ",".join(store["test"]) == "1,2,3":
|
||||
document.documentElement.classList.add("ok")
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,8 +3,8 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<mpy-config>
|
||||
29
pyscript.core/tests/js-integration/loader/index.html
Normal file
29
pyscript.core/tests/js-integration/loader/index.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../../dist/core.css">
|
||||
<script type="module">
|
||||
import '../../../dist/core.js';
|
||||
|
||||
addEventListener('py:progress', ({ detail }) => {
|
||||
document.body.append(
|
||||
detail,
|
||||
document.createElement('br'),
|
||||
);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<py-config>
|
||||
packages = ["matplotlib"]
|
||||
</py-config>
|
||||
<script type="py" worker>
|
||||
from pyscript import document
|
||||
from sys import version
|
||||
document.body.append(document.createElement('hr'), version)
|
||||
document.documentElement.classList.add('ok')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,8 +9,8 @@
|
||||
document.documentElement.classList.add('done');
|
||||
});
|
||||
</script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy">
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal Main</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<style>.xterm { padding: .5rem; }</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal Main</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<style>.xterm { padding: .5rem; }</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<style>.xterm { padding: .5rem; }</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal Main</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<style>.xterm { padding: .5rem; }</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@pyscript/core storage</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" async>
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<script type="module" src="../../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" async>
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<title>named workers</title>
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<script type="module" src="../../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy" async>
|
||||
1
pyscript.core/tests/manual/a.py
Normal file
1
pyscript.core/tests/manual/a.py
Normal file
@@ -0,0 +1 @@
|
||||
print("a")
|
||||
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module">
|
||||
import '../dist/core.js';
|
||||
import '../../dist/core.js';
|
||||
|
||||
document.body.append('loading ...', document.createElement('br'));
|
||||
|
||||
21
pyscript.core/tests/manual/async.html
Normal file
21
pyscript.core/tests/manual/async.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<py-script>
|
||||
import asyncio
|
||||
print('py-script sleep')
|
||||
await asyncio.sleep(1)
|
||||
print('py-script done')
|
||||
</py-script>
|
||||
<script type="py">
|
||||
import asyncio
|
||||
print('script-py sleep')
|
||||
await asyncio.sleep(1)
|
||||
print('script-py done')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Media Example</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py" src="camera.py" async></script>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next Plugin Bug?</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py">
|
||||
@@ -3,9 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module">
|
||||
import { hooks } from "../dist/core.js";
|
||||
import { hooks } from "../../dist/core.js";
|
||||
hooks.main.codeBeforeRun.add('print(0)');
|
||||
hooks.main.codeAfterRun.add('print(2)');
|
||||
</script>
|
||||
@@ -4,11 +4,11 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Error</title>
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<py-config>
|
||||
[[fetch]]
|
||||
files = ["a.py"]
|
||||
files = ["./a.py"]
|
||||
</py-config>
|
||||
<script type="py" worker>
|
||||
import a
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next Plugin</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<py-config>
|
||||
files = [
|
||||
</py-config>
|
||||
@@ -1,8 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<script type="module">
|
||||
customElements.whenDefined('py-script').then(PyScript => {
|
||||
const textContent = `
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Next</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<script type="module">
|
||||
const loader = document.querySelector('#loader');
|
||||
loader.showModal();
|
||||
@@ -7,8 +7,8 @@
|
||||
<script>
|
||||
addEventListener("py:all-done", ({ type }) => console.log(type));
|
||||
</script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py" worker async>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next Plugin</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<script type="py">
|
||||
print(1, 2, 3)
|
||||
first()
|
||||
@@ -1,8 +1,8 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
@@ -7,8 +7,8 @@
|
||||
<script>
|
||||
addEventListener("py:ready", console.log);
|
||||
</script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py">
|
||||
@@ -7,8 +7,8 @@
|
||||
<script>
|
||||
addEventListener("py:ready", console.log);
|
||||
</script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<py-script>
|
||||
16
pyscript.core/tests/manual/interpreter.html
Normal file
16
pyscript.core/tests/manual/interpreter.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Pyodide Worker Version</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py" config='{"interpreter":"https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.mjs"}' worker>
|
||||
import pyodide
|
||||
print(pyodide.__version__)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy">
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>PyScript Test</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py-editor">
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PyScript Next No Plugin</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
<py-config>plugins = ['!error']</py-config>
|
||||
<script type="py">
|
||||
print(1, 2, 3)
|
||||
15
pyscript.core/tests/manual/py-editor-failure.html
Normal file
15
pyscript.core/tests/manual/py-editor-failure.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal</title>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="mpy-editor" src="./shenanigans.py" setup></script>
|
||||
<script type="mpy-editor" config="./404.toml" setup></script>
|
||||
<script type="mpy-editor" src="./404.py" setup></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py-editor">
|
||||
@@ -3,8 +3,8 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py" async>
|
||||
3
pyscript.core/tests/manual/shenanigans.py
Normal file
3
pyscript.core/tests/manual/shenanigans.py
Normal file
@@ -0,0 +1,3 @@
|
||||
import sys
|
||||
|
||||
print(sys.shenanigans)
|
||||
@@ -5,13 +5,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Config</title>
|
||||
<script type="module">
|
||||
import { config } from "../dist/core.js";
|
||||
import { config } from "../../dist/core.js";
|
||||
console.log(config.mpy);
|
||||
</script>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<mpy-config>
|
||||
[[fetch]]
|
||||
files = ["a.py"]
|
||||
files = ["./a.py"]
|
||||
</mpy-config>
|
||||
<script type="mpy">
|
||||
import a
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@pyscript/core</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<py-script id="first">
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Next: Display HTML</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<py-script>
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Next: When Decorator</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Click for a hi!</p>
|
||||
@@ -4,11 +4,11 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyScript Next</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<link rel="stylesheet" href="../../dist/core.css">
|
||||
|
||||
<!-- the PyWorker approach -->
|
||||
<script type="module">
|
||||
import { PyWorker, whenDefined } from '../dist/core.js';
|
||||
import { PyWorker, whenDefined } from '../../dist/core.js';
|
||||
whenDefined('py').then(() => {
|
||||
PyWorker('./worker.py', {config: {fetch: [{files: ['./a.py']}]}});
|
||||
});
|
||||
@@ -4,8 +4,8 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Arrr - Piratical PyScript</title>
|
||||
<link rel="stylesheet" href="../dist/core.css" />
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<link rel="stylesheet" href="../../dist/core.css" />
|
||||
<script type="module" src="../../dist/core.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Arrr</h1>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user