Files
server/src/main/resources/static/js/customAssets.js

86 lines
2.5 KiB
JavaScript

const assetModal = document.getElementById("custom-asset-modal");
const userSourceTextArea = document.getElementById("custom-asset-code");
const formErrorWrapper = document.getElementById("custom-asset-error");
const jsErrorTitle = document.getElementById("js-error-title");
const jsErrorDetails = document.getElementById("js-error-details");
function toggleCustomAssetModal(event) {
if (event !== undefined && event.target !== event.currentTarget) {
return;
}
if (assetModal.classList.contains("hidden")) {
assetModal.classList.remove("hidden");
} else {
assetModal.classList.add("hidden");
}
}
function submitCodeAsset(formEvent) {
formEvent.preventDefault();
const src = userSourceTextArea.value;
const error = getUserJavaScriptSourceError(src);
if (error) {
jsErrorTitle.textContent = error.title;
jsErrorDetails.textContent = error.details;
formErrorWrapper.classList.remove("hidden");
return false;
}
formErrorWrapper.classList.add("hidden");
jsErrorTitle.textContent = "";
jsErrorDetails.textContent = "";
return false;
}
function getUserJavaScriptSourceError(src) {
let ast;
try {
ast = acorn.parse(src, {
ecmaVersion: "latest",
sourceType: "script",
});
} catch (e) {
return { title: "Syntax Error", details: e.message };
}
let hasInit = false;
let hasTick = false;
for (const node of ast.body) {
if (node.type !== "ExpressionStatement") continue;
const expr = node.expression;
if (expr.type !== "AssignmentExpression") continue;
const left = expr.left;
const right = expr.right;
if (
left.type === "MemberExpression" &&
left.object.type === "Identifier" &&
left.object.name === "exports" &&
left.property.type === "Identifier" &&
(right.type === "FunctionExpression" || right.type === "ArrowFunctionExpression")
) {
if (left.property.name === "init") hasInit = true;
if (left.property.name === "tick") hasTick = true;
}
}
if (!hasInit) {
return {
title: "Missing function: init",
details: "You must assign a function to exports.init",
};
}
if (!hasTick) {
return {
title: "Missing function: tick",
details: "You must assign a function to exports.tick",
};
}
return undefined;
}