Spaces:
Running
Running
File size: 4,571 Bytes
9fd0d3c 3e2c114 0dea17b 3e2c114 0dea17b 3e2c114 9a770de 3e2c114 09b1f7a 3e2c114 0dea17b 3e2c114 9a770de 3e2c114 9a770de 3e2c114 9a770de 3e2c114 c94f5bc 3e2c114 3ab14b8 3e2c114 3ab14b8 3e2c114 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
import gradio as gr
def update_ui(code):
try:
# Strip out scripts and handle them separately to avoid security issues
from bs4 import BeautifulSoup
soup = BeautifulSoup(code, 'html.parser')
scripts = soup.find_all('script')
for script in scripts:
script.decompose() # Remove script tags from HTML to prevent direct execution
# Rebuild HTML without scripts for direct rendering
html_content = str(soup)
# Collect script content
js_content = '\n'.join([script.string for script in scripts if script.string])
# Return HTML wrapped in a div and scripts in a way that Gradio can handle
return f"""
<div style="border: 1px solid #ccc; padding: 10px; height: 400px; overflow: auto;">
{html_content}
</div>
<script>
{js_content}
</script>
""", None
except Exception as e:
return "", str(e)
def interface():
with gr.Blocks() as demo:
gr.Markdown("# Learn Frontend UI")
with gr.Row():
code_input = gr.Code(label="Write your HTML/CSS/JS here", language="html")
with gr.Column():
ui_preview = gr.HTML(label="UI Preview")
error_output = gr.Textbox(label="Error", interactive=False)
code_input.change(
fn=update_ui,
inputs=code_input,
outputs=[ui_preview, error_output]
)
# Example codes remain the same, but ensure the snake game is full HTML
with gr.Accordion("HTML/CSS/JS Code Examples", open=False):
with gr.Column():
example_buttons = []
example_codes = [
# ... (other examples remain unchanged)
("""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body { margin: 0; padding: 0; }
#gameCanvas { border: 1px solid black; }
</style>
</head>
<body>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<script>
let canvas = document.getElementById('gameCanvas');
let ctx = canvas.getContext('2d');
let snake = [{x: 10, y: 10}];
let food = {x: 15, y: 15};
let gameLoop;
function init() {
gameLoop = setInterval(game, 100);
}
function game() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snake.unshift({x: snake[0].x, y: snake[0].y});
snake[0].x += 1; // Simple movement for demonstration
if(snake[0].x > 39) snake[0].x = 0; // Wrap around
ctx.fillStyle = "green";
snake.forEach(part => {
ctx.fillRect(part.x * 10, part.y * 10, 10, 10);
});
ctx.fillStyle = "red";
ctx.fillRect(food.x * 10, food.y * 10, 10, 10);
if(snake[0].x == food.x && snake[0].y == food.y) {
food.x = Math.floor(Math.random() * 40);
food.y = Math.floor(Math.random() * 40);
} else {
snake.pop();
}
}
// Start the game
init();
</script>
</body>
</html>
""", "Snake Game"),
]
for code, label in example_codes:
button = gr.Button(label)
example_buttons.append(button)
button.click(fn=lambda x=code: x, outputs=code_input)
return demo
if __name__ == "__main__":
demo = interface()
demo.launch() |