File size: 3,013 Bytes
9fd0d3c
095df03
9fd0d3c
 
 
095df03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fd0d3c
095df03
9fd0d3c
 
 
095df03
9fd0d3c
20083c5
9fd0d3c
 
 
095df03
 
9fd0d3c
095df03
e6d5c9e
095df03
 
 
038159a
095df03
 
e6d5c9e
095df03
 
 
 
 
 
 
 
 
e6d5c9e
 
095df03
e6d5c9e
 
 
 
9fd0d3c
 
 
 
 
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
import gradio as gr
import re

def update_ui(code):
    try:
        # Extract HTML, CSS, and JavaScript using regex
        html_content = re.search(r'<html[^>]*>[\s\S]*?<\/html>', code, re.IGNORECASE)
        if html_content:
            html_content = html_content.group(0)
        else:
            html_content = code  # If no <html> tag, assume all is HTML content

        # Extract CSS if present in a <style> tag
        css_content = re.search(r'<style[^>]*>[\s\S]*?<\/style>', code, re.IGNORECASE)
        css_string = ''
        if css_content:
            css_string = css_content.group(0)
        
        # Remove <style> tags for direct application
        css_only = re.sub(r'<style>|<\/style>', '', css_string) if css_string else ''

        # Extract JavaScript if present in a <script> tag
        js_content = re.search(r'<script[^>]*>[\s\S]*?<\/script>', code, re.IGNORECASE)
        js_string = ''
        if js_content:
            js_string = js_content.group(0)
        
        # Remove <script> tags for Gradio's js= parameter
        js_only = re.sub(r'<script>|<\/script>', '', js_string) if js_string else ''

        # Combine HTML with CSS for preview, but we'll handle JS separately
        ui_output = f"""
        <style>{css_only}</style>
        {html_content}
        """
        return ui_output, js_only, 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", lines=500, language="html")
            with gr.Column():
                ui_preview = gr.HTML(label="UI Preview")
                error_output = gr.Textbox(label="Error", interactive=False)
                # Hidden output to store JavaScript for _js execution
                js_output = gr.Textbox(visible=False)
        
        # Use _js to execute JavaScript in the browser context
        code_input.change(
            fn=update_ui,
            inputs=code_input,
            outputs=[ui_preview, js_output, error_output],
            js="""
            function(code, ui_output, js_code) {
                // Create a temporary div to parse the HTML
                const tempDiv = document.createElement('div');
                tempDiv.innerHTML = ui_output;

                // If there's JavaScript code, execute it
                if (js_code) {
                    const script = document.createElement('script');
                    script.textContent = js_code;
                    document.body.appendChild(script);
                    // Clean up script tag after execution to prevent duplicates
                    setTimeout(() => script.remove(), 0);
                }

                // Return the HTML content for Gradio to display
                return tempDiv.innerHTML;
            }
            """
        )
    return demo

if __name__ == "__main__":
    demo = interface()
    demo.launch()