Fix #1538 - use same customElements Registry utilities (#1542)

This commit is contained in:
Andrea Giammarchi
2023-06-16 15:34:05 +02:00
committed by GitHub
parent 6df5905b2b
commit bccd5e3750
8 changed files with 194 additions and 113 deletions

View File

@@ -1,71 +1,16 @@
import { $x, $$ } from "basic-devtools";
import { $$ } from "basic-devtools";
import xworker from "./worker/class.js";
import { handle, interpreters } from "./script-handler.js";
import { all, assign, create, defineProperty } from "./utils.js";
import { registry, selectors, prefixes } from "./interpreters.js";
import { PLUGINS_SELECTORS, handlePlugin } from "./plugins.js";
import { handle } from "./script-handler.js";
import { assign } from "./utils.js";
import { selectors, prefixes } from "./interpreters.js";
import { CUSTOM_SELECTORS, handleCustomType } from "./custom-types.js";
import { listener, addAllListeners } from "./listeners.js";
export { registerPlugin } from "./plugins.js";
export { define, whenDefined } from "./custom-types.js";
export const XWorker = xworker();
const RUNTIME_SELECTOR = selectors.join(",");
// ensure both interpreter and its queue are awaited then returns the interpreter
const awaitRuntime = async (key) => {
if (interpreters.has(key)) {
const { interpreter, queue } = interpreters.get(key);
return (await all([interpreter, queue]))[0];
}
const available = interpreters.size
? `Available interpreters are: ${[...interpreters.keys()]
.map((r) => `"${r}"`)
.join(", ")}.`
: `There are no interpreters in this page.`;
throw new Error(`The interpreter "${key}" was not found. ${available}`);
};
defineProperty(globalThis, "pyscript", {
value: {
env: new Proxy(create(null), { get: (_, name) => awaitRuntime(name) }),
},
});
let index = 0;
globalThis.__events = new Map();
// attributes are tested via integration / e2e
/* c8 ignore next 17 */
const listener = async (event) => {
const { type, currentTarget } = event;
for (let { name, value, ownerElement: el } of $x(
`./@*[${prefixes.map((p) => `name()="${p}${type}"`).join(" or ")}]`,
currentTarget,
)) {
name = name.slice(0, -(type.length + 1));
const interpreter = await awaitRuntime(
el.getAttribute(`${name}-env`) || name,
);
const i = index++;
try {
globalThis.__events.set(i, event);
registry.get(name).runEvent(interpreter, value, i);
} finally {
globalThis.__events.delete(i);
}
}
};
// attributes are tested via integration / e2e
/* c8 ignore next 8 */
for (let { name, ownerElement: el } of $x(
`.//@*[${prefixes.map((p) => `starts-with(name(),"${p}")`).join(" or ")}]`,
)) {
name = name.slice(name.lastIndexOf("-") + 1);
if (name !== "env") el.addEventListener(name, listener);
}
const INTERPRETER_SELECTORS = selectors.join(",");
const mo = new MutationObserver((records) => {
for (const { type, target, attributeName, addedNodes } of records) {
@@ -92,12 +37,15 @@ const mo = new MutationObserver((records) => {
}
for (const node of addedNodes) {
if (node.nodeType === 1) {
if (node.matches(RUNTIME_SELECTOR)) handle(node);
addAllListeners(node);
if (node.matches(INTERPRETER_SELECTORS)) handle(node);
else {
$$(RUNTIME_SELECTOR, node).forEach(handle);
if (!PLUGINS_SELECTORS.length) continue;
handlePlugin(node);
$$(PLUGINS_SELECTORS.join(","), node).forEach(handlePlugin);
$$(INTERPRETER_SELECTORS, node).forEach(handle);
if (!CUSTOM_SELECTORS.length) continue;
handleCustomType(node);
$$(CUSTOM_SELECTORS.join(","), node).forEach(
handleCustomType,
);
}
}
}
@@ -116,4 +64,5 @@ assign(Element.prototype, {
},
});
$$(RUNTIME_SELECTOR, observe(document)).forEach(handle);
addAllListeners(observe(document));
$$(INTERPRETER_SELECTORS, document).forEach(handle);