mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-20 02:37:41 -05:00
* updated MicroPython to latest in order to have `globals` API available * reduced code around helpers for both MicroPython and Pyodide as now these are more aligned * updated all dependencies and brought in latest [coincident/window](https://github.com/WebReflection/coincident#coincidentwindow) goodness to any `xworker`, preserving the `sync` previous behavior * using [@ungap/structured-clone/json](https://github.com/ungap/structured-clone#tojson) as *coincident* default `parse` and `stringify` utility to allow recursive and more complex data to travel back from the *Worker* (forward data is still fully [structured clone algorithm compatible](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm)) * renamed all *plugin/s* references to *custom/s* as plugin as a word was too misleading * changed *custom types* helpers logic to allow any single node to have its own version of the interpreter wrapper, and all the extra fields it carries with it, including a way to augment every interpreter execution, among as every worker code execution * created a `custom` folder where I've landed the very first `pyscript.js` custom type * created an exhaustive test page to demonstrate the current abilities of *PyScript Next* among its ability to expose utilities that can be used to create *PyScript* plugins
69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
import { $$ } from "basic-devtools";
|
|
|
|
import xworker from "./worker/class.js";
|
|
import { handle } from "./script-handler.js";
|
|
import { assign } from "./utils.js";
|
|
import { selectors, prefixes } from "./interpreters.js";
|
|
import { CUSTOM_SELECTORS, handleCustomType } from "./custom.js";
|
|
import { listener, addAllListeners } from "./listeners.js";
|
|
|
|
export { define, whenDefined } from "./custom.js";
|
|
export const XWorker = xworker();
|
|
|
|
const INTERPRETER_SELECTORS = selectors.join(",");
|
|
|
|
const mo = new MutationObserver((records) => {
|
|
for (const { type, target, attributeName, addedNodes } of records) {
|
|
// attributes are tested via integration / e2e
|
|
/* c8 ignore next 17 */
|
|
if (type === "attributes") {
|
|
const i = attributeName.lastIndexOf("-") + 1;
|
|
if (i) {
|
|
const prefix = attributeName.slice(0, i);
|
|
for (const p of prefixes) {
|
|
if (prefix === p) {
|
|
const type = attributeName.slice(i);
|
|
if (type !== "env") {
|
|
const method = target.hasAttribute(attributeName)
|
|
? "add"
|
|
: "remove";
|
|
target[`${method}EventListener`](type, listener);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
for (const node of addedNodes) {
|
|
if (node.nodeType === 1) {
|
|
addAllListeners(node);
|
|
if (node.matches(INTERPRETER_SELECTORS)) handle(node);
|
|
else {
|
|
$$(INTERPRETER_SELECTORS, node).forEach(handle);
|
|
if (!CUSTOM_SELECTORS.length) continue;
|
|
handleCustomType(node);
|
|
$$(CUSTOM_SELECTORS.join(","), node).forEach(
|
|
handleCustomType,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
const observe = (root) => {
|
|
mo.observe(root, { childList: true, subtree: true, attributes: true });
|
|
return root;
|
|
};
|
|
|
|
const { attachShadow } = Element.prototype;
|
|
assign(Element.prototype, {
|
|
attachShadow(init) {
|
|
return observe(attachShadow.call(this, init));
|
|
},
|
|
});
|
|
|
|
addAllListeners(observe(document));
|
|
$$(INTERPRETER_SELECTORS, document).forEach(handle);
|