260 lines
8.7 KiB
JavaScript
260 lines
8.7 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const editor = ace.edit("editor");
|
|
editor.session.setMode("ace/mode/lua");
|
|
|
|
loadSettings();
|
|
|
|
const obfuscateBtn = document.getElementById('obfuscate-btn');
|
|
const saveBtn = document.getElementById('save-btn');
|
|
const loadBtn = document.getElementById('load-btn');
|
|
const clearOutputBtn = document.getElementById('clear-output-btn');
|
|
const obfuscatedOutput = document.getElementById('obfuscated-output');
|
|
const loader = document.getElementById('loader');
|
|
const versionSpan = document.getElementById('luau-version');
|
|
const examplesMenu = document.getElementById('examples-menu');
|
|
const saveStatus = document.getElementById('save-status');
|
|
|
|
const LS_CODE_KEY = 'luau-saved-code';
|
|
const LS_SETTINGS_KEY = 'luau-editor-settings';
|
|
|
|
const editorThemes = [
|
|
'ambiance', 'chaos', 'chrome', 'clouds', 'cobalt',
|
|
'crimson_editor', 'dawn', 'dracula', 'dreamweaver', 'eclipse',
|
|
'github', 'gob', 'gruvbox', 'idle_fingers', 'iplastic',
|
|
'katzenmilch', 'kr_theme', 'kuroir', 'merbivore', 'merbivore_soft',
|
|
'mono_industrial', 'monokai', 'nord_dark', 'pastel_on_dark', 'solarized_dark',
|
|
'solarized_light', 'sqlserver', 'terminal', 'textmate', 'tomorrow',
|
|
'tomorrow_night', 'tomorrow_night_blue', 'tomorrow_night_bright', 'tomorrow_night_eighties',
|
|
'twilight', 'vibrant_ink', 'xcode'
|
|
];
|
|
|
|
let editorSettings = {};
|
|
|
|
// --- Editor and Snippet Setup ---
|
|
const examples = [
|
|
{
|
|
title: 'Hello World',
|
|
code: 'print("Hello, world!")'
|
|
},
|
|
{
|
|
title: 'Variables & Types',
|
|
code: '-- Luau has types that you can optionally add!\n\n' +
|
|
'local message: string = "Hello, Luau!"\n' +
|
|
'local version: number = 1.0\n' +
|
|
'local isAwesome: boolean = true\n\n' +
|
|
'print(message, type(message))\n' +
|
|
'print("Version:", version, type(version))\n' +
|
|
'print("Is it awesome?", isAwesome, type(isAwesome))'
|
|
},
|
|
{
|
|
title: 'Loops',
|
|
code: 'print("Counting from 1 to 5:")\n' +
|
|
'for i = 1, 5 do\n' +
|
|
' print("Number:", i)\n' +
|
|
'end\n\n' +
|
|
'local t = {"apple", "banana", "cherry"}\n' +
|
|
'print("\nIterating through a table:")\n' +
|
|
'for _, fruit in ipairs(t) do\n' +
|
|
' print("- " .. fruit)\n' +
|
|
'end'
|
|
},
|
|
{
|
|
title: 'Functions',
|
|
code: 'function greet(name: string): string\n' +
|
|
' return "Hello, " .. name .. "!"\n' +
|
|
'end\n\n' +
|
|
'local message = greet("User")\n' +
|
|
'print(message)\n\n' +
|
|
'-- Function with a type alias\n' +
|
|
'type Player = { name: string, score: number }\n\n' +
|
|
'local function displayPlayer(p: Player)\n' +
|
|
' print("Player: " .. p.name .. ", Score: " .. p.score)\n' +
|
|
'end\n\n' +
|
|
'local player1: Player = { name = "Alice", score = 100 }\n' +
|
|
'displayPlayer(player1)'
|
|
}
|
|
];
|
|
|
|
examples.forEach((example, index) => {
|
|
const li = document.createElement('li');
|
|
const a = document.createElement('a');
|
|
a.classList.add('dropdown-item');
|
|
a.href = '#';
|
|
a.textContent = example.title;
|
|
a.dataset.index = index;
|
|
li.appendChild(a);
|
|
examplesMenu.appendChild(li);
|
|
});
|
|
|
|
examplesMenu.addEventListener('click', (e) => {
|
|
if (e.target.tagName === 'A') {
|
|
e.preventDefault();
|
|
const index = e.target.dataset.index;
|
|
if (index) {
|
|
editor.setValue(examples[index].code, 1); // 1 moves cursor to the end
|
|
}
|
|
}
|
|
});
|
|
|
|
// --- Settings Modal Logic ---
|
|
const themeSelect = document.getElementById('theme-select');
|
|
const fontSizeInput = document.getElementById('font-size-input');
|
|
const softWrapCheck = document.getElementById('soft-wrap-check');
|
|
|
|
function applySettings() {
|
|
editor.setTheme("ace/theme/" + editorSettings.theme);
|
|
editor.setFontSize(editorSettings.fontSize);
|
|
editor.session.setUseWrapMode(editorSettings.softWrap);
|
|
|
|
// Update UI controls to reflect current settings
|
|
themeSelect.value = editorSettings.theme;
|
|
fontSizeInput.value = editorSettings.fontSize;
|
|
softWrapCheck.checked = editorSettings.softWrap;
|
|
}
|
|
|
|
function saveSettings() {
|
|
try {
|
|
localStorage.setItem(LS_SETTINGS_KEY, JSON.stringify(editorSettings));
|
|
} catch (e) {
|
|
console.error("Failed to save settings:", e);
|
|
}
|
|
}
|
|
|
|
function loadSettings() {
|
|
const defaults = {
|
|
theme: 'tomorrow_night',
|
|
fontSize: 14,
|
|
softWrap: false
|
|
};
|
|
|
|
try {
|
|
const saved = localStorage.getItem(LS_SETTINGS_KEY);
|
|
if (saved) {
|
|
editorSettings = Object.assign({}, defaults, JSON.parse(saved));
|
|
} else {
|
|
editorSettings = defaults;
|
|
}
|
|
} catch (e) {
|
|
console.error("Failed to load settings:", e);
|
|
editorSettings = defaults;
|
|
}
|
|
applySettings();
|
|
}
|
|
|
|
// Populate theme dropdown
|
|
editorThemes.forEach(theme => {
|
|
const option = document.createElement('option');
|
|
option.value = theme;
|
|
option.textContent = theme.split('_').map(w => w[0].toUpperCase() + w.substr(1)).join(' ');
|
|
themeSelect.appendChild(option);
|
|
});
|
|
|
|
// Settings event listeners
|
|
themeSelect.addEventListener('change', () => {
|
|
editorSettings.theme = themeSelect.value;
|
|
applySettings();
|
|
saveSettings();
|
|
});
|
|
|
|
fontSizeInput.addEventListener('input', () => {
|
|
editorSettings.fontSize = parseInt(fontSizeInput.value, 10);
|
|
applySettings();
|
|
saveSettings();
|
|
});
|
|
|
|
softWrapCheck.addEventListener('change', () => {
|
|
editorSettings.softWrap = softWrapCheck.checked;
|
|
applySettings();
|
|
saveSettings();
|
|
});
|
|
|
|
|
|
// --- Local Storage and UI Logic ---
|
|
|
|
function showSaveStatus(message, duration = 2000) {
|
|
saveStatus.textContent = message;
|
|
setTimeout(() => {
|
|
saveStatus.textContent = '';
|
|
}, duration);
|
|
}
|
|
|
|
saveBtn.addEventListener('click', () => {
|
|
try {
|
|
localStorage.setItem(LS_CODE_KEY, editor.getValue());
|
|
showSaveStatus('Code saved!');
|
|
} catch (e) {
|
|
console.error("Failed to save to localStorage:", e);
|
|
showSaveStatus('Error saving!');
|
|
}
|
|
});
|
|
|
|
loadBtn.addEventListener('click', () => {
|
|
const savedCode = localStorage.getItem(LS_CODE_KEY);
|
|
if (savedCode) {
|
|
editor.setValue(savedCode, 1);
|
|
showSaveStatus('Code restored!');
|
|
} else {
|
|
showSaveStatus('No code saved yet.');
|
|
}
|
|
});
|
|
|
|
clearOutputBtn.addEventListener('click', () => {
|
|
obfuscatedOutput.textContent = '';
|
|
});
|
|
|
|
// --- Load initial code ---
|
|
const savedCode = localStorage.getItem(LS_CODE_KEY);
|
|
if (savedCode) {
|
|
editor.setValue(savedCode, 1);
|
|
} else {
|
|
// Load default example if nothing is saved
|
|
editor.setValue(examples[0].code, 1);
|
|
}
|
|
|
|
versionSpan.textContent = `Luau Obfuscator`;
|
|
|
|
obfuscateBtn.addEventListener('click', async () => {
|
|
const code = editor.getValue();
|
|
obfuscatedOutput.textContent = '';
|
|
loader.style.display = 'block';
|
|
obfuscateBtn.disabled = true;
|
|
|
|
// Give the UI a moment to update
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
try {
|
|
const formData = new FormData();
|
|
formData.append('code', code);
|
|
|
|
const response = await fetch('obfuscator.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
});
|
|
|
|
if (response.ok) {
|
|
const result = await response.text();
|
|
obfuscatedOutput.textContent = result;
|
|
} else {
|
|
obfuscatedOutput.textContent = `Error: ${response.statusText}`;
|
|
}
|
|
|
|
} catch (err) {
|
|
obfuscatedOutput.textContent = `Error: ${err.message}`;
|
|
console.error(err);
|
|
} finally {
|
|
loader.style.display = 'none';
|
|
obfuscateBtn.disabled = false;
|
|
}
|
|
});
|
|
|
|
// --- Split View ---
|
|
Split(['#split-0', '#split-1'], {
|
|
sizes: [50, 50],
|
|
minSize: 200,
|
|
gutterSize: 8,
|
|
onDrag: function() {
|
|
editor.resize();
|
|
}
|
|
});
|
|
});
|