experimental/piranha_playground/static/script.js (193 lines of code) (raw):

(async () => { /** * UI elements in the script */ const elements = { codeInputBefore: document.getElementById("code-input-before"), codeIntputAfter: document.getElementById("code-input-after"), languageSelect: document.getElementById("language-select"), queryInput: document.getElementById("query-input"), explanationInput: document.getElementById("explanation-input"), submitFolderButton: document.getElementById("submit-button-folder"), submitButtonInfer: document.getElementById("submit-button-infer"), submitButtonImprovement: document.getElementById( "submit-button-improvement", ), testButton: document.getElementById("submit-button-test"), }; elements.languageSelect.addEventListener("change", handleLanguageChange); handleLanguageChange(); const editors = { codeBefore: CodeMirror.fromTextArea( elements.codeInputBefore, editorOptions("javascript"), ), codeAfter: CodeMirror.fromTextArea( elements.codeIntputAfter, editorOptions("javascript"), ), queryEditor: CodeMirror.fromTextArea( elements.queryInput, editorOptions("toml"), ), requirementsEditor: CodeMirror.fromTextArea(elements.explanationInput, { lineWrapping: true, }), }; function editorOptions(mode) { return { lineNumbers: true, showCursorWhenSelecting: true, mode: mode, }; } /** * Function to load a script dynamically * @param {string} url - The URL of the script to load * @param {Function} callback - Function to be called once the script has loaded */ function loadScript(url, callback) { const script = document.createElement("script"); script.type = "text/javascript"; script.src = url; script.onload = callback; document.body.appendChild(script); } function handleLanguageChange() { const selectedLanguage = elements.languageSelect.value; const langName = selectedLanguage === "java" ? "javascript" : selectedLanguage; const scriptUrl = `${codeMirror}/mode/${langName}/${langName}.js`; loadScript(scriptUrl, function () { editors.codeBefore.setOption("mode", langName); editors.codeAfter.setOption("mode", langName); }); } // Define a list of button names let buttonNames = ["test", "infer", "improvement", "folder"]; // Initial text of the buttons let buttonElements = {}; buttonNames.forEach((name) => { let element = document.getElementById("submit-button-" + name); buttonElements[name] = element.innerText; }); function displayButton(disabled, textContent, name) { const button = document.getElementById("submit-button-" + name); const buttonText = document.getElementById("button-text-" + name); const spinner = document.getElementById("spinner-" + name); button.disabled = disabled; spinner.style.display = disabled ? "inline-block" : "none"; buttonText.textContent = textContent; return button; } elements.submitFolderButton.addEventListener("click", emitRefactorEvent); elements.submitButtonInfer.addEventListener("click", emitInferEvent); elements.submitButtonImprovement.addEventListener("click", emitImproveEvent); elements.testButton.addEventListener("click", emitTestEvent); /* Function to make an async request to the provided URL * @param {string} url - The URL to send the request to * @param {Object} requestData - The request data to be sent * @param {string} buttonName - The name of the button that triggered the request * @param {Function} onSuccess - Function to be called if the request was successful */ async function makeRequest(url, requestData, buttonName, onSuccess) { const button = displayButton(true, "Processing...", buttonName); const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(requestData), }); const data = await response.json(); if (response.status === 200) { onSuccess(data); button.classList.add("btn-success"); displayButton(false, `Success`, buttonName); } else { button.classList.add("btn-danger"); displayButton(false, `Error`, buttonName); showAlert(data.error || "An error occurred", "danger"); } setTimeout(() => { button.classList.remove("btn-success", "btn-danger"); displayButton(false, buttonElements[buttonName], buttonName); }, 3000); } async function emitInferEvent() { const sourceCode = editors.codeBefore.getValue(); const targetCode = editors.codeAfter.getValue(); const language = elements.languageSelect.value; await makeRequest( "http://127.0.0.1:5000/infer_rule_graph", { source_code: sourceCode, target_code: targetCode, language: language, }, "infer", (data) => { updateInterface(data.rules); // emitImproveEventAux("general"); }, ); } async function emitTestEvent() { const sourceCode = editors.codeBefore.getValue(); const rules = editors.queryEditor.getValue(); const language = elements.languageSelect.value; await makeRequest( "http://127.0.0.1:5000/test_rule", { source_code: sourceCode, rules: rules, language: language, }, "test", (data) => { editors.codeAfter.setValue(data.refactored_code); }, ); } async function emitRefactorEvent() { const folderPath = document.getElementById("folder-input").value; const rules = editors.queryEditor.getValue(); const language = elements.languageSelect.value; await makeRequest( "http://127.0.0.1:5000/refactor_codebase", { rules: rules, folder_path: folderPath, language: language, }, "folder", (data) => {}, ); } async function emitImproveEvent() { await emitImproveEventAux("user"); } async function emitImproveEventAux(option) { const sourceCode = editors.codeBefore.getValue(); const targetCode = editors.codeAfter.getValue(); const language = elements.languageSelect.value; const rules = editors.queryEditor.getValue(); const requirements = editors.requirementsEditor.getValue(); await makeRequest( "http://127.0.0.1:5000/improve_rule_graph", { source_code: sourceCode, target_code: targetCode, language: language, rules: rules, requirements: requirements, option: option, }, "improvement", (data) => { updateInterface(data.rule); }, ); } /** * Function to update the interface with the provided rule, and display the improvement button * @param rule: The rule to be displayed */ function updateInterface(rule) { document.getElementById("explanation-container").style.display = "block"; document.getElementById("submit-button-improvement").style.display = "block"; editors.queryEditor.setValue(rule); if (editors.requirementsEditor.getValue() === "") { editors.requirementsEditor.setValue(" "); } } /** * Display an alert message * @param {string} message - The message to be displayed * @param {string} alertType - The type of the alert to be displayed */ function showAlert(message, alertType) { const alertPlaceholder = document.getElementById("alert-placeholder"); const alertBox = document.createElement("div"); alertBox.className = `alert alert-${alertType} fade show`; alertBox.role = "alert"; alertBox.innerHTML = message; alertPlaceholder.appendChild(alertBox); setTimeout(() => { alertPlaceholder.removeChild(alertBox); }, 3000); } })();