🌐
index.html
Back
📝 Html ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ace Editor with Block Code Overlay</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.32.8/ace.js"></script> <style> body { margin: 0; padding: 20px; font-family: Arial, sans-serif; background: #f5f5f5; } #editor { width: 100%; height: 500px; border: 1px solid #ccc; border-radius: 4px; } .controls { margin-bottom: 10px; } button { padding: 8px 16px; margin-right: 10px; background: #007acc; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background: #005a9e; } .blocks-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); z-index: 1000; display: none; } .blocks-container { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; height: 85%; background: #2c3e50; border-radius: 10px; padding: 20px; overflow: auto; } .blocks-header { color: white; margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; } .close-btn { background: #e74c3c; color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer; } .blocks-canvas { background: #34495e; border-radius: 8px; padding: 20px; min-height: 600px; position: relative; } .code-block { background: #3498db; border-radius: 8px; padding: 15px; margin: 10px; color: white; font-family: 'Courier New', monospace; position: relative; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); cursor: move; border: 2px solid transparent; display: inline-block; min-width: 200px; } .code-block:hover { border-color: #2980b9; transform: translateY(-2px); } .block-function { background: #e74c3c; } .block-if { background: #f39c12; } .block-loop { background: #27ae60; } .block-variable { background: #9b59b6; } .block-container { border: 2px dashed rgba(255, 255, 255, 0.3); border-radius: 8px; padding: 10px; margin: 5px; background: rgba(0, 0, 0, 0.1); } .block-nested { margin: 8px; position: relative; } .block-label { font-size: 12px; background: rgba(0, 0, 0, 0.2); padding: 2px 6px; border-radius: 3px; margin-bottom: 8px; display: inline-block; } .block-content { white-space: pre-wrap; font-size: 14px; line-height: 1.4; } .connector { position: absolute; width: 20px; height: 20px; background: rgba(255, 255, 255, 0.8); border-radius: 50%; top: 50%; transform: translateY(-50%); } .connector-in { left: -10px; } .connector-out { right: -10px; } .block-close { background: #7f8c8d; font-size: 12px; padding: 8px 12px; margin: 5px; border-radius: 4px; color: white; font-family: 'Courier New', monospace; } </style> </head> <body> <h1>Ace Editor with Block Code View</h1> <div class="controls"> <button id="blocksBtn">Open Blocks</button> <button id="runBtn">Run Code</button> </div> <div id="editor">function calculateSum(a, b) { console.log("Starting calculation"); if (a > 0 && b > 0) { console.log("Both numbers are positive"); let result = a + b; for (let i = 0; i < 3; i++) { console.log("Processing step: " + i); result = result + i; } return result; } else { console.log("One or both numbers are not positive"); return 0; } } calculateSum(5, 10);</div> <!-- Blocks Overlay --> <div class="blocks-overlay" id="blocksOverlay"> <div class="blocks-container"> <div class="blocks-header"> <h2>Block Code View</h2> <button class="close-btn" id="closeBlocks">Close</button> </div> <div class="blocks-canvas" id="blocksCanvas"> <!-- Blocks will be generated here --> </div> </div> </div> <script> var editor = ace.edit("editor"); editor.setTheme("ace/theme/monokai"); editor.session.setMode("ace/mode/javascript"); function parseCodeToBlocks() { const code = editor.getValue(); const lines = code.split('\n'); const canvas = document.getElementById('blocksCanvas'); canvas.innerHTML = ''; let blockStack = [canvas]; // Stack to keep track of containers let openBlockStack = []; // Stack to track open blocks waiting for their closing brace let lastIndentLevel = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (line === '' || line.startsWith('//')) continue; // Calculate indentation level const indent = lines[i].length - lines[i].trimLeft().length; const currentIndentLevel = Math.floor(indent / 4); // Handle closing braces if (line === '}' || line.includes('}')) { // Add the closing brace to the most recent open block if (openBlockStack.length > 0) { const openBlock = openBlockStack.pop(); const closeBlock = document.createElement('div'); closeBlock.className = 'block-close'; closeBlock.innerHTML = `<div class="block-content">${line}</div>`; openBlock.appendChild(closeBlock); } // Pop the container since we're closing it if (blockStack.length > 1) { blockStack.pop(); } lastIndentLevel = Math.max(0, currentIndentLevel); continue; } // Handle indentation changes for opening blocks if (currentIndentLevel > lastIndentLevel) { // Going deeper - find the last created block and add container to it if (openBlockStack.length > 0) { const parentBlock = openBlockStack[openBlockStack.length - 1]; const container = document.createElement('div'); container.className = 'block-container'; parentBlock.appendChild(container); blockStack.push(container); } } else if (currentIndentLevel < lastIndentLevel) { // Going back up - pop containers from stack const levelDiff = lastIndentLevel - currentIndentLevel; for (let j = 0; j < levelDiff; j++) { if (blockStack.length > 1) { blockStack.pop(); } if (openBlockStack.length > 0) { openBlockStack.pop(); } } } lastIndentLevel = currentIndentLevel; // Determine block type and content let blockType = 'code-block'; let blockLabel = 'Code'; let isBlockOpener = false; if (line.includes('function')) { blockType += ' block-function'; blockLabel = 'Function'; isBlockOpener = true; } else if (line.includes('if') || line.includes('else')) { blockType += ' block-if'; blockLabel = 'Condition'; isBlockOpener = true; } else if (line.includes('for') || line.includes('while')) { blockType += ' block-loop'; blockLabel = 'Loop'; isBlockOpener = true; } else if (line.includes('let') || line.includes('const') || line.includes('var')) { blockType += ' block-variable'; blockLabel = 'Variable'; } else if (line.includes('try') || line.includes('catch')) { blockType += ' block-if'; blockLabel = 'Try/Catch'; isBlockOpener = true; } // Create block element const block = document.createElement('div'); block.className = blockType; block.innerHTML = ` <div class="connector connector-in"></div> <div class="block-label">${blockLabel}</div> <div class="block-content">${line}</div> <div class="connector connector-out"></div> `; // Add to current container const currentContainer = blockStack[blockStack.length - 1]; currentContainer.appendChild(block); // If this block opens a new scope, track it for its closing brace if (isBlockOpener && line.includes('{')) { openBlockStack.push(block); } // Make blocks draggable makeDraggable(block); } } function makeDraggable(element) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; element.onmousedown = dragMouseDown; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; element.style.top = (element.offsetTop - pos2) + "px"; element.style.left = (element.offsetLeft - pos1) + "px"; element.style.position = "absolute"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; } } // Event listeners document.getElementById('blocksBtn').addEventListener('click', function() { parseCodeToBlocks(); document.getElementById('blocksOverlay').style.display = 'block'; }); document.getElementById('closeBlocks').addEventListener('click', function() { document.getElementById('blocksOverlay').style.display = 'none'; }); document.getElementById('runBtn').addEventListener('click', function() { try { const code = editor.getValue(); eval(code); } catch (error) { console.error('Error running code:', error); } }); // Close overlay when clicking outside document.getElementById('blocksOverlay').addEventListener('click', function(e) { if (e.target === this) { this.style.display = 'none'; } }); </script> </body> </html>