Spaces:
Sleeping
Sleeping
Update index.html
Browse files- index.html +120 -46
index.html
CHANGED
|
@@ -14,10 +14,8 @@
|
|
| 14 |
<meta property="og:description" content="JavaRunner is a mobile-friendly online Java IDE. Write, run, save, and download Java code. Perfect for beginners like Ragini Didi.">
|
| 15 |
<meta property="og:type" content="website">
|
| 16 |
|
| 17 |
-
<!--
|
| 18 |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
|
| 19 |
-
|
| 20 |
-
<!-- Font Awesome -->
|
| 21 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
| 22 |
|
| 23 |
<!-- CodeMirror -->
|
|
@@ -31,8 +29,8 @@
|
|
| 31 |
<style>
|
| 32 |
:root {
|
| 33 |
--bg:#0b1b2b;
|
| 34 |
-
--glass: rgba(255,255,255,0.
|
| 35 |
-
--glass-hover: rgba(255,255,255,0.
|
| 36 |
--accent:#6c8cff;
|
| 37 |
--accent-light:#8be5d0;
|
| 38 |
--text:#e6eef8;
|
|
@@ -40,65 +38,67 @@
|
|
| 40 |
--radius:14px;
|
| 41 |
--shadow:0 8px 30px rgba(2,6,23,0.6);
|
| 42 |
}
|
| 43 |
-
*{box-sizing:border-box;}
|
| 44 |
body{
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
background: linear-gradient(180deg, #071227, #0d1a2b);
|
| 48 |
color:var(--text);
|
| 49 |
-
min-height:100vh;
|
| 50 |
display:flex;
|
| 51 |
flex-direction:column;
|
| 52 |
-
|
| 53 |
padding:10px;
|
| 54 |
}
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
/* App container */
|
| 60 |
.app{
|
| 61 |
display:flex;
|
| 62 |
-
flex
|
| 63 |
gap:12px;
|
| 64 |
-
width:100%;
|
| 65 |
max-width:1200px;
|
| 66 |
-
|
| 67 |
}
|
| 68 |
.panel{
|
| 69 |
background: var(--glass);
|
| 70 |
backdrop-filter: blur(12px) saturate(1.1);
|
| 71 |
border-radius: var(--radius);
|
|
|
|
| 72 |
padding:12px;
|
| 73 |
box-shadow: var(--shadow);
|
| 74 |
-
border:1px solid rgba(255,255,255,0.08);
|
| 75 |
transition: transform .2s ease, box-shadow .2s ease;
|
| 76 |
}
|
| 77 |
.panel:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(8,14,40,0.5);}
|
| 78 |
|
| 79 |
/* Sidebar */
|
| 80 |
.sidebar{
|
| 81 |
-
flex:0 0
|
| 82 |
display:flex;
|
| 83 |
flex-direction:column;
|
| 84 |
gap:10px;
|
| 85 |
-
height:calc(100vh -
|
| 86 |
}
|
| 87 |
.sidebar-header{
|
| 88 |
display:flex;
|
| 89 |
justify-content:space-between;
|
| 90 |
align-items:center;
|
| 91 |
-
margin-bottom:8px;
|
| 92 |
}
|
| 93 |
-
.brand{
|
| 94 |
-
font-weight:700;
|
| 95 |
-
font-size:18px;
|
| 96 |
-
color:var(--accent);
|
| 97 |
-
display:flex;
|
| 98 |
-
align-items:center;
|
| 99 |
-
gap:8px;
|
| 100 |
-
}
|
| 101 |
-
.brand i{font-size:20px;}
|
| 102 |
.file-list{
|
| 103 |
flex:1;
|
| 104 |
overflow-y:auto;
|
|
@@ -110,17 +110,17 @@ a:hover{color:var(--accent-light);}
|
|
| 110 |
display:flex;
|
| 111 |
justify-content:space-between;
|
| 112 |
align-items:center;
|
| 113 |
-
padding:
|
| 114 |
border-radius:10px;
|
| 115 |
cursor:pointer;
|
| 116 |
background: rgba(255,255,255,0.02);
|
| 117 |
-
transition:0.
|
| 118 |
}
|
| 119 |
.file-item:hover{background:var(--glass-hover);}
|
| 120 |
.file-item.active{background:rgba(108,140,255,0.12);color:#fff;}
|
| 121 |
.file-actions{display:flex;gap:6px;align-items:center;}
|
| 122 |
|
| 123 |
-
/* Editor
|
| 124 |
.editor-area{
|
| 125 |
flex:1;
|
| 126 |
display:flex;
|
|
@@ -128,8 +128,17 @@ a:hover{color:var(--accent-light);}
|
|
| 128 |
gap:8px;
|
| 129 |
min-height:400px;
|
| 130 |
}
|
| 131 |
-
.cm-wrap{
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
/* Buttons */
|
| 135 |
.btn{
|
|
@@ -142,7 +151,7 @@ a:hover{color:var(--accent-light);}
|
|
| 142 |
display:inline-flex;
|
| 143 |
align-items:center;
|
| 144 |
gap:6px;
|
| 145 |
-
transition:all .15s ease;
|
| 146 |
}
|
| 147 |
.btn:hover{color:#fff;transform:translateY(-2px);background:var(--glass-hover);}
|
| 148 |
.btn-primary{
|
|
@@ -152,6 +161,8 @@ a:hover{color:var(--accent-light);}
|
|
| 152 |
font-weight:700;
|
| 153 |
border:none;
|
| 154 |
}
|
|
|
|
|
|
|
| 155 |
.console{
|
| 156 |
margin-top:6px;
|
| 157 |
background: rgba(0,0,0,0.5);
|
|
@@ -168,27 +179,30 @@ footer{
|
|
| 168 |
text-align:center;
|
| 169 |
color:var(--muted);
|
| 170 |
font-size:14px;
|
| 171 |
-
padding:12px 0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
}
|
| 173 |
-
footer .note{color:#c7d7ff;font-weight:600;}
|
| 174 |
|
| 175 |
/* Responsive */
|
| 176 |
-
@media
|
| 177 |
.app{flex-direction:column;}
|
| 178 |
.sidebar{width:100%;height:auto;order:2;}
|
| 179 |
.editor-area{order:1;}
|
| 180 |
.CodeMirror{height:300px;}
|
| 181 |
}
|
| 182 |
-
@media
|
| 183 |
body{padding:6px;}
|
| 184 |
-
.brand{font-size:
|
| 185 |
.btn{padding:5px 8px;font-size:13px;}
|
| 186 |
.btn-primary{padding:8px 10px;font-size:14px;}
|
| 187 |
}
|
| 188 |
</style>
|
| 189 |
</head>
|
| 190 |
<body>
|
| 191 |
-
<header
|
| 192 |
<div class="brand"><i class="fa-solid fa-rocket"></i> JavaRunner</div>
|
| 193 |
</header>
|
| 194 |
|
|
@@ -238,10 +252,14 @@ const editor = CodeMirror(document.getElementById('editor'),{
|
|
| 238 |
indentUnit:4,
|
| 239 |
autoCloseBrackets:true,
|
| 240 |
matchBrackets:true,
|
| 241 |
-
value
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
});
|
| 243 |
|
| 244 |
-
// Resize editor
|
| 245 |
function resizeEditor(){
|
| 246 |
const wrap=document.querySelector('.CodeMirror');
|
| 247 |
if(!wrap) return;
|
|
@@ -252,7 +270,7 @@ function resizeEditor(){
|
|
| 252 |
window.addEventListener('resize',resizeEditor);
|
| 253 |
setTimeout(resizeEditor,200);
|
| 254 |
|
| 255 |
-
// ---------- Local storage ----------
|
| 256 |
let files=JSON.parse(localStorage.getItem('javaRunner_files')||'{}');
|
| 257 |
let active=localStorage.getItem('javaRunner_active')||null;
|
| 258 |
const fileListEl=document.getElementById('fileList');
|
|
@@ -281,9 +299,65 @@ function renderFiles(filter=''){
|
|
| 281 |
});
|
| 282 |
}
|
| 283 |
|
|
|
|
| 284 |
function newFile(){
|
| 285 |
let name=prompt('Filename (end with .java)','Main.java');
|
| 286 |
if(!name) return;if(!name.endsWith('.java')){alert('Filename must end with .java');return;}
|
| 287 |
if(files[name]){alert('File exists');return;}
|
| 288 |
const classname=name.replace('.java','').replace(/[^A-Za-z0-9_]/g,'')||'Main';
|
| 289 |
-
files[name]=`class ${classname} {\n public static void main(String[] args) {\
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
<meta property="og:description" content="JavaRunner is a mobile-friendly online Java IDE. Write, run, save, and download Java code. Perfect for beginners like Ragini Didi.">
|
| 15 |
<meta property="og:type" content="website">
|
| 16 |
|
| 17 |
+
<!-- Fonts & Icons -->
|
| 18 |
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
|
|
|
|
|
|
|
| 19 |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
| 20 |
|
| 21 |
<!-- CodeMirror -->
|
|
|
|
| 29 |
<style>
|
| 30 |
:root {
|
| 31 |
--bg:#0b1b2b;
|
| 32 |
+
--glass: rgba(255,255,255,0.06);
|
| 33 |
+
--glass-hover: rgba(255,255,255,0.1);
|
| 34 |
--accent:#6c8cff;
|
| 35 |
--accent-light:#8be5d0;
|
| 36 |
--text:#e6eef8;
|
|
|
|
| 38 |
--radius:14px;
|
| 39 |
--shadow:0 8px 30px rgba(2,6,23,0.6);
|
| 40 |
}
|
| 41 |
+
*{box-sizing:border-box;margin:0;padding:0;}
|
| 42 |
body{
|
| 43 |
+
font-family:'Inter',sans-serif;
|
| 44 |
+
background:linear-gradient(180deg, #071227, #0d1a2b);
|
|
|
|
| 45 |
color:var(--text);
|
|
|
|
| 46 |
display:flex;
|
| 47 |
flex-direction:column;
|
| 48 |
+
min-height:100vh;
|
| 49 |
padding:10px;
|
| 50 |
}
|
| 51 |
+
|
| 52 |
+
/* Header */
|
| 53 |
+
header{
|
| 54 |
+
display:flex;
|
| 55 |
+
justify-content:center;
|
| 56 |
+
align-items:center;
|
| 57 |
+
margin-bottom:12px;
|
| 58 |
+
}
|
| 59 |
+
.brand{
|
| 60 |
+
font-weight:700;
|
| 61 |
+
font-size:24px;
|
| 62 |
+
color:var(--accent);
|
| 63 |
+
display:flex;
|
| 64 |
+
align-items:center;
|
| 65 |
+
gap:10px;
|
| 66 |
+
text-shadow: 1px 1px 4px rgba(0,0,0,0.5);
|
| 67 |
+
}
|
| 68 |
+
.brand i{font-size:28px;}
|
| 69 |
|
| 70 |
/* App container */
|
| 71 |
.app{
|
| 72 |
display:flex;
|
| 73 |
+
flex:1;
|
| 74 |
gap:12px;
|
|
|
|
| 75 |
max-width:1200px;
|
| 76 |
+
width:100%;
|
| 77 |
}
|
| 78 |
.panel{
|
| 79 |
background: var(--glass);
|
| 80 |
backdrop-filter: blur(12px) saturate(1.1);
|
| 81 |
border-radius: var(--radius);
|
| 82 |
+
border:1px solid rgba(255,255,255,0.08);
|
| 83 |
padding:12px;
|
| 84 |
box-shadow: var(--shadow);
|
|
|
|
| 85 |
transition: transform .2s ease, box-shadow .2s ease;
|
| 86 |
}
|
| 87 |
.panel:hover{transform:translateY(-3px);box-shadow:0 16px 40px rgba(8,14,40,0.5);}
|
| 88 |
|
| 89 |
/* Sidebar */
|
| 90 |
.sidebar{
|
| 91 |
+
flex:0 0 260px;
|
| 92 |
display:flex;
|
| 93 |
flex-direction:column;
|
| 94 |
gap:10px;
|
| 95 |
+
height:calc(100vh - 60px);
|
| 96 |
}
|
| 97 |
.sidebar-header{
|
| 98 |
display:flex;
|
| 99 |
justify-content:space-between;
|
| 100 |
align-items:center;
|
|
|
|
| 101 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
.file-list{
|
| 103 |
flex:1;
|
| 104 |
overflow-y:auto;
|
|
|
|
| 110 |
display:flex;
|
| 111 |
justify-content:space-between;
|
| 112 |
align-items:center;
|
| 113 |
+
padding:8px;
|
| 114 |
border-radius:10px;
|
| 115 |
cursor:pointer;
|
| 116 |
background: rgba(255,255,255,0.02);
|
| 117 |
+
transition:0.2s;
|
| 118 |
}
|
| 119 |
.file-item:hover{background:var(--glass-hover);}
|
| 120 |
.file-item.active{background:rgba(108,140,255,0.12);color:#fff;}
|
| 121 |
.file-actions{display:flex;gap:6px;align-items:center;}
|
| 122 |
|
| 123 |
+
/* Editor */
|
| 124 |
.editor-area{
|
| 125 |
flex:1;
|
| 126 |
display:flex;
|
|
|
|
| 128 |
gap:8px;
|
| 129 |
min-height:400px;
|
| 130 |
}
|
| 131 |
+
.cm-wrap{
|
| 132 |
+
border-radius:12px;
|
| 133 |
+
overflow:hidden;
|
| 134 |
+
border:1px solid rgba(255,255,255,0.04);
|
| 135 |
+
}
|
| 136 |
+
.CodeMirror{
|
| 137 |
+
height:calc(100vh - 300px);
|
| 138 |
+
background: rgba(2,6,23,0.7);
|
| 139 |
+
color:#e8f1ff;
|
| 140 |
+
font-size:14px;
|
| 141 |
+
}
|
| 142 |
|
| 143 |
/* Buttons */
|
| 144 |
.btn{
|
|
|
|
| 151 |
display:inline-flex;
|
| 152 |
align-items:center;
|
| 153 |
gap:6px;
|
| 154 |
+
transition: all .15s ease;
|
| 155 |
}
|
| 156 |
.btn:hover{color:#fff;transform:translateY(-2px);background:var(--glass-hover);}
|
| 157 |
.btn-primary{
|
|
|
|
| 161 |
font-weight:700;
|
| 162 |
border:none;
|
| 163 |
}
|
| 164 |
+
|
| 165 |
+
/* Console */
|
| 166 |
.console{
|
| 167 |
margin-top:6px;
|
| 168 |
background: rgba(0,0,0,0.5);
|
|
|
|
| 179 |
text-align:center;
|
| 180 |
color:var(--muted);
|
| 181 |
font-size:14px;
|
| 182 |
+
padding:12px 0 6px 0;
|
| 183 |
+
}
|
| 184 |
+
footer .note{
|
| 185 |
+
color:#c7d7ff;
|
| 186 |
+
font-weight:600;
|
| 187 |
}
|
|
|
|
| 188 |
|
| 189 |
/* Responsive */
|
| 190 |
+
@media(max-width:900px){
|
| 191 |
.app{flex-direction:column;}
|
| 192 |
.sidebar{width:100%;height:auto;order:2;}
|
| 193 |
.editor-area{order:1;}
|
| 194 |
.CodeMirror{height:300px;}
|
| 195 |
}
|
| 196 |
+
@media(max-width:480px){
|
| 197 |
body{padding:6px;}
|
| 198 |
+
.brand{font-size:20px;}
|
| 199 |
.btn{padding:5px 8px;font-size:13px;}
|
| 200 |
.btn-primary{padding:8px 10px;font-size:14px;}
|
| 201 |
}
|
| 202 |
</style>
|
| 203 |
</head>
|
| 204 |
<body>
|
| 205 |
+
<header>
|
| 206 |
<div class="brand"><i class="fa-solid fa-rocket"></i> JavaRunner</div>
|
| 207 |
</header>
|
| 208 |
|
|
|
|
| 252 |
indentUnit:4,
|
| 253 |
autoCloseBrackets:true,
|
| 254 |
matchBrackets:true,
|
| 255 |
+
value:`class Main {
|
| 256 |
+
public static void main(String[] args) {
|
| 257 |
+
System.out.println("Hello Ragini Didi!");
|
| 258 |
+
}
|
| 259 |
+
}`
|
| 260 |
});
|
| 261 |
|
| 262 |
+
// Resize editor dynamically
|
| 263 |
function resizeEditor(){
|
| 264 |
const wrap=document.querySelector('.CodeMirror');
|
| 265 |
if(!wrap) return;
|
|
|
|
| 270 |
window.addEventListener('resize',resizeEditor);
|
| 271 |
setTimeout(resizeEditor,200);
|
| 272 |
|
| 273 |
+
// ---------- Local storage & file management ----------
|
| 274 |
let files=JSON.parse(localStorage.getItem('javaRunner_files')||'{}');
|
| 275 |
let active=localStorage.getItem('javaRunner_active')||null;
|
| 276 |
const fileListEl=document.getElementById('fileList');
|
|
|
|
| 299 |
});
|
| 300 |
}
|
| 301 |
|
| 302 |
+
// File actions
|
| 303 |
function newFile(){
|
| 304 |
let name=prompt('Filename (end with .java)','Main.java');
|
| 305 |
if(!name) return;if(!name.endsWith('.java')){alert('Filename must end with .java');return;}
|
| 306 |
if(files[name]){alert('File exists');return;}
|
| 307 |
const classname=name.replace('.java','').replace(/[^A-Za-z0-9_]/g,'')||'Main';
|
| 308 |
+
files[name]=`class ${classname} {\n public static void main(String[] args) {\n System.out.println("Hello Ragini Didi!");\n }\n}`;
|
| 309 |
+
saveToStorage();
|
| 310 |
+
setActive(name);
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
function openFile(name){setActive(name);}
|
| 314 |
+
function deleteFile(name){if(confirm(`Delete file ${name}?`)){delete files[name]; if(active===name) active=null; saveToStorage(); setActive(active);}}
|
| 315 |
+
function saveFile(){if(!active){alert('No active file'); return;} files[active]=editor.getValue(); saveToStorage(); consoleEl.innerText='Saved successfully!';}
|
| 316 |
+
function downloadFile(){if(!active){alert('No active file'); return;} const blob=new Blob([editor.getValue()],{type:'text/plain'}); const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download=active; a.click(); URL.revokeObjectURL(a.href);}
|
| 317 |
+
function formatCode(){const value=editor.getValue(); editor.setValue(value.split('\n').map(l=>l.trimStart()).join('\n'));}
|
| 318 |
+
function cutText(){editor.execCommand('cut');}
|
| 319 |
+
function copyText(){editor.execCommand('copy');}
|
| 320 |
+
function pasteText(){editor.execCommand('paste');}
|
| 321 |
+
|
| 322 |
+
// Run code (connect to backend /run API)
|
| 323 |
+
async function runCode(){
|
| 324 |
+
if(!active){alert('No active file'); return;}
|
| 325 |
+
consoleEl.innerText='Running...';
|
| 326 |
+
const code=editor.getValue();
|
| 327 |
+
try{
|
| 328 |
+
const res=await fetch('/run', {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({code})});
|
| 329 |
+
const data=await res.json();
|
| 330 |
+
consoleEl.innerText=data.output||data.error||'No output';
|
| 331 |
+
}catch(e){consoleEl.innerText='Error running code: '+e.message;}
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
// Search files
|
| 335 |
+
document.getElementById('searchFile').addEventListener('input',e=>renderFiles(e.target.value));
|
| 336 |
+
|
| 337 |
+
// Button events
|
| 338 |
+
document.getElementById('newBtn').addEventListener('click',newFile);
|
| 339 |
+
document.getElementById('saveBtn').addEventListener('click',saveFile);
|
| 340 |
+
document.getElementById('downloadBtn').addEventListener('click',downloadFile);
|
| 341 |
+
document.getElementById('formatBtn').addEventListener('click',formatCode);
|
| 342 |
+
document.getElementById('cutBtn').addEventListener('click',cutText);
|
| 343 |
+
document.getElementById('copyBtn').addEventListener('click',copyText);
|
| 344 |
+
document.getElementById('pasteBtn').addEventListener('click',pasteText);
|
| 345 |
+
document.getElementById('runBtn').addEventListener('click',runCode);
|
| 346 |
+
|
| 347 |
+
// Import files
|
| 348 |
+
const fileInput=document.getElementById('fileInput');
|
| 349 |
+
document.getElementById('importBtn').addEventListener('click',()=>fileInput.click());
|
| 350 |
+
fileInput.addEventListener('change',e=>{
|
| 351 |
+
const file=e.target.files[0];
|
| 352 |
+
if(!file) return;
|
| 353 |
+
const reader=new FileReader();
|
| 354 |
+
reader.onload=()=>{files[file.name]=reader.result; saveToStorage(); setActive(file.name);}
|
| 355 |
+
reader.readAsText(file);
|
| 356 |
+
});
|
| 357 |
+
|
| 358 |
+
// Initialize
|
| 359 |
+
setActive(active);
|
| 360 |
+
renderFiles();
|
| 361 |
+
</script>
|
| 362 |
+
</body>
|
| 363 |
+
</html>
|