add blocks

This commit is contained in:
2025-12-17 10:14:13 +02:00
parent 18a31be0b1
commit d78a6bedd5
54 changed files with 2755 additions and 10 deletions

View File

@@ -0,0 +1,29 @@
# Go Функции
### Доступные Функции:
<div id="container">
<button id="bt_newFunc" class="all_button">Создать</button>
<div id="alternative">
<select id="functionList">
<option value="">— Выбери —</option>
</select>
<input id="newfunction" placeholder="Название функции" class="hidden" >
</div>
<button id="bt_save" class="all_button">Сохранить</button>
<button id="bt_delete" class="all_button">Удалить</button><br>
</div>
<label>Go Код:</label><br>
<div id="codeWrapper">
<div id="lineNumbers"></div>
<div id="Wrapper"></div>
<textarea id="code"></textarea>
</div><br>
<button id="bt_compile" class="all_button">Компилировать</button>
<button id="bt_run" class="all_button">Запустить</button><br>
<label>Входные аргументы:</label><br>
<input id="input" /><br>
<label>Ответ сервера:</label><br>
<div id="output"></div>

View File

@@ -0,0 +1,168 @@
let nameStringMod;
let fCodeMod;
// универсальный обработчик (вставка, ввод, удаление, drag-drop)
function triggerUpdate() {
// вставка иногда происходит позже — даём браузеру завершить операцию
requestAnimationFrame(updateLineNumbers);
}
// ВСЕ события, которые могут менять текст
code.addEventListener("input", triggerUpdate);
code.addEventListener("change", triggerUpdate);
code.addEventListener("keyup", triggerUpdate);
code.addEventListener("paste", triggerUpdate);
code.addEventListener("cut", triggerUpdate);
code.addEventListener("drop", triggerUpdate);
code.addEventListener("scroll", () => {
lineNumbers.scrollTop = code.scrollTop;
});
lineNumbers.addEventListener("scroll", () => {
code.scrollTop = lineNumbers.scrollTop;
});
updateLineNumbers();
// ==================== ORIGINAL FUNCTIONS ====================
async function loadSource(name) {
if (name != ""){
const res = await fetch("/api/functions/source/" + name);
if (!res.ok) {
code.value = "// source not found or binary only";
return;
}
const text = await res.text();
code.value = text;
} else {
code.value = "";
}
// ВАЖНО: обновляем нумерацию после программной вставки
requestAnimationFrame(updateLineNumbers);
}
async function loadFunctions() {
const res = await fetch('/api/functions/list');
const list = await res.json();
//const sel = document.getElementById('functionList');
functionList.innerHTML = '<option value="">— select —</option>';
// Object.keys(list).forEach(name => {
list.forEach(name => {
const opt = document.createElement('option');
opt.value = name;
opt.textContent = name;
functionList.appendChild(opt);
});
}
function newf() {
if (functionList.className == 'hidden'){
functionList.classList.remove('hidden');
newfunction.classList.add('hidden');
selectFunction();
bt_newFunc.innerText = 'Создать';
} else {
functionList.classList.add('hidden');
newfunction.classList.remove('hidden');
code.value = "";
newfunction.value = "";
bt_newFunc.innerText = 'Выбрать';
}
code.value = "";
updateLineNumbers();
}
function selectFunction() {
loadSource(functionList.value);
requestAnimationFrame(updateLineNumbers);
}
async function compile() {
if (functionList.value != ""){
const res = await fetch('/api/functions/compile', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
functionName: functionList.value,
goCode: code.value
})
});
output.textContent = await res.text();
}
}
async function savef() {
if (newfunction.className == "hidden"){
// console.log("open")
popup("old")
} else {
// console.log("new")
// await popup("new",() => {return;});
await popup("new");
return;
console.log("test")
}
if (newfunction.value != ""){
const res = await fetch('/api/functions/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
functionName: newfunction.value,
goCode: code.value
})
});
output.textContent = await res.text();
}
}
async function run() {
const name = functionList.value;
const res = await fetch('/api/functions/run/' + name, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: input.value })
});
output.textContent = await res.text();
}
function updateLineNumbers() {
const lines = code.value.split("\n").length;
let html = "";
for (let i = 1; i <= lines; i++) {
html += i + "<br>";
}
lineNumbers.innerHTML = html;
}
function btLoc(){
if (newfunction.value != ""){
//bt_newFunc.disabled = true;
nameStringMod = true;
} else {
//bt_newFunc.disabled = false
nameStringMod = false;
}
}
function codLoc(){
fCodeMod = true;
fCodeMod = false;
}
//bt_save.addEventListener("click", () => {const message = 'Пустое сообщение'; popup(message);});
functionList.addEventListener("change", selectFunction);
bt_newFunc.addEventListener("click", newf);
bt_compile.addEventListener("click", compile);
bt_run.addEventListener("click", run);
bt_save.addEventListener("click", savef);
newfunction.addEventListener("input", btLoc)
code.addEventListener("input", codLoc)
loadFunctions();

View File

@@ -0,0 +1,30 @@
textarea { width: 100%; height: 200px; }
#codeWrapper {display: flex; width: 100%; position: relative; height: 300px; border: 1px solid #aaa;
border-radius: 4px; overflow: hidden; margin-top: 10px;}
#lineNumbers {width: 40px; background: #f0f0f0; padding-right: 5px; text-align: right; user-select: none;
font-family: monospace; font-size: 12px; line-height: 1.2em; color: #555; border-right: 1px solid #ccc;
overflow-y: hidden; overflow-x: hidden;}
#code {width: 100%; margin-left: 5px; white-space: pre; overflow: auto; height: 100%; border: none; outline: none;
resize: none; box-sizing: border-box; font-family: monospace; font-size: 12px; line-height: 1.2em; padding: 0;}
#output {display: flex; width: 100%; position: relative; height: 100px; border: 1px solid #aaa;
border-radius: 4px; overflow: hidden; margin-top: 10px;}
#input { width: 100%; height: 20px; margin-bottom: 10px; margin-top: 10px; padding-top: 8px; padding-left: 0px;
padding-right: 0px; }
#container {display: flex; align-items: center; gap: 10px; height: 40px; margin-top: 10px; margin-bottom: 10px}
#alternative {position: relative; width: 500px; height: 100%;}
#functionList, #newfunction{box-sizing: border-box; font-size: 16px; padding: 5px;height: 100%;}
#functionList, #newfunction {position: absolute; top: 0; left: 0; width: 100%; }
/* #bt_newFunc{width: 90px;} , #bt_newFunc, #bt_compile
#bt_run{height: 40px; width: 90px; margin-top: 10px; margin-bottom: 10px} */
.hidden {display: none;}
.all_button{height: 40px; width: 120px; margin-top: 10px; margin-bottom: 10px}
/* Полупрозрачный фон */
.overlay {position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5);
display: flex; justify-content: center; align-items: center; z-index: 1000;}
/* Центральный div */
.popup {width: 400px; height: 150px; background: white; border-radius: 10px; display: flex;
flex-direction: column; justify-content: center; align-items: center; padding: 20px;
box-shadow: 0 0 10px rgba(0,0,0,0.3);}
.popup button {margin-top: 20px; padding: 5px 10px;}