mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
[next] Errors on ambiguous/conflicting code intents (#1724)
This commit is contained in:
committed by
GitHub
parent
e8d5138cfa
commit
f6decfd93d
@@ -9,6 +9,7 @@ import { queryTarget } from "../node_modules/polyscript/esm/script-handler.js";
|
||||
import { dedent, dispatch } from "../node_modules/polyscript/esm/utils.js";
|
||||
import { Hook } from "../node_modules/polyscript/esm/worker/hooks.js";
|
||||
|
||||
import { ErrorCode } from "./exceptions.js";
|
||||
import sync from "./sync.js";
|
||||
import stdlib from "./stdlib.js";
|
||||
import { config, plugins, error } from "./config.js";
|
||||
@@ -40,6 +41,36 @@ const after = () => {
|
||||
delete document.currentScript;
|
||||
};
|
||||
|
||||
/**
|
||||
* Some content that might contain Python/JS comments only.
|
||||
* @param {string} text some content to evaluate
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasCommentsOnly = (text) =>
|
||||
!text
|
||||
.replace(/\/\*[\s\S]*?\*\//g, "")
|
||||
.replace(/^\s*(?:\/\/|#).*/gm, "")
|
||||
.trim();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Element} scriptOrPyScript the element with possible `src` or `worker` content
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasAmbiguousContent = (
|
||||
io,
|
||||
{ localName, textContent, attributes: { src, worker } },
|
||||
) => {
|
||||
// any `src` or a non-empty `worker` attribute + not just comments
|
||||
if ((src || worker?.value) && !hasCommentsOnly(textContent)) {
|
||||
io.stderr(
|
||||
`(${ErrorCode.CONFLICTING_CODE}) a ${localName} tag has content shadowed by attributes`,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a generic DOM Element, tries to fetch the 'src' attribute, if present.
|
||||
* It either throws an error if the 'src' can't be fetched or it returns a fallback
|
||||
@@ -172,6 +203,7 @@ error ||
|
||||
callback(pyodide, element);
|
||||
|
||||
if (isScript(element)) {
|
||||
if (hasAmbiguousContent(pyodide.io, element)) return;
|
||||
const {
|
||||
attributes: { async: isAsync, target },
|
||||
} = element;
|
||||
@@ -222,6 +254,7 @@ class PyScriptElement extends HTMLElement {
|
||||
if (!this.executed) {
|
||||
this.executed = true;
|
||||
const { io, run, runAsync } = await this._pyodide.promise;
|
||||
if (hasAmbiguousContent(io, this)) return;
|
||||
const runner = this.hasAttribute("async") ? runAsync : run;
|
||||
this.srcCode = await fetchSource(this, io, !this.childElementCount);
|
||||
this.replaceChildren();
|
||||
|
||||
@@ -7,19 +7,20 @@ const CLOSEBUTTON =
|
||||
*/
|
||||
export const ErrorCode = {
|
||||
GENERIC: "PY0000", // Use this only for development then change to a more specific error code
|
||||
FETCH_ERROR: "PY0001",
|
||||
FETCH_NAME_ERROR: "PY0002",
|
||||
// Currently these are created depending on error code received from fetching
|
||||
FETCH_UNAUTHORIZED_ERROR: "PY0401",
|
||||
FETCH_FORBIDDEN_ERROR: "PY0403",
|
||||
FETCH_NOT_FOUND_ERROR: "PY0404",
|
||||
FETCH_SERVER_ERROR: "PY0500",
|
||||
FETCH_UNAVAILABLE_ERROR: "PY0503",
|
||||
CONFLICTING_CODE: "PY0409",
|
||||
BAD_CONFIG: "PY1000",
|
||||
MICROPIP_INSTALL_ERROR: "PY1001",
|
||||
BAD_PLUGIN_FILE_EXTENSION: "PY2000",
|
||||
NO_DEFAULT_EXPORT: "PY2001",
|
||||
TOP_LEVEL_AWAIT: "PY9000",
|
||||
// Currently these are created depending on error code received from fetching
|
||||
FETCH_ERROR: "PY0001",
|
||||
FETCH_NAME_ERROR: "PY0002",
|
||||
FETCH_UNAUTHORIZED_ERROR: "PY0401",
|
||||
FETCH_FORBIDDEN_ERROR: "PY0403",
|
||||
FETCH_NOT_FOUND_ERROR: "PY0404",
|
||||
FETCH_SERVER_ERROR: "PY0500",
|
||||
FETCH_UNAVAILABLE_ERROR: "PY0503",
|
||||
};
|
||||
|
||||
export class UserError extends Error {
|
||||
|
||||
Reference in New Issue
Block a user