File size: 6,676 Bytes
4b286f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
from pathlib import Path

gradio_lite_html_template = Path('templates/gradio-lite/gradio-lite-template.html').read_text()
stlite_html_template = Path('templates/stlite/stlite-template.html').read_text()
stlite_snippet_template = Path('templates/stlite/stlite-snippet-template.html').read_text()


def starting_app_code(demo_type):
    if demo_type == 'gradio-lite':
        return Path('templates/gradio-lite/gradio_lite_starting_code.py').read_text()
    elif demo_type == 'stlite':
        return Path('templates/stlite/stlite_starting_code.py').read_text().replace('`', r'\`')
    raise NotImplementedError(f'{demo_type} is not a supported demo type')


def load_js(demo_type):
    if demo_type == 'gradio-lite':
        return f"""() => {{
            const htmlString = '<iframe class="my-frame" width="100%" height="512px" src="about:blank"></iframe>';
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, 'text/html');
            const iframe = doc.querySelector('.my-frame'); 
            const div = document.getElementById('gradioDemoDiv');
            div.appendChild(iframe);
    
            const frame = document.querySelector('.my-frame');
            frame.contentWindow.document.open('text/html', 'replace');
            frame.contentWindow.document.write(`{gradio_lite_html_template}`);
            frame.contentWindow.document.close();
        }}"""
    elif demo_type == 'stlite':
        return f"""() => {{
            const htmlString = '<iframe id="demo-iframe" width="100%" height="512px" src="about:blank"></iframe>';
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, 'text/html');
            const iframe = doc.getElementById('demo-iframe'); 
            const div = document.getElementById('stliteDemoDiv');
            div.appendChild(iframe);
            
            const template = `{stlite_html_template.replace('STARTING_CODE', starting_app_code(demo_type))}`;
            console.log(template);
            
            const frame = document.getElementById('demo-iframe');
            frame.contentWindow.document.open();
            frame.contentWindow.document.write(template);
            frame.contentWindow.document.close();
        }}"""
    raise NotImplementedError(f'{demo_type} is not a supported demo type')


def update_iframe_js(demo_type):
    if demo_type == 'gradio-lite':
        #  TODO: Works but is inefficient because the iframe has to be reloaded each time
        return f"""(code) => {{
            const pattern = /# APP CODE START(.*?)# APP CODE END/gs;
            const template = `{gradio_lite_html_template}`;
            const completedTemplate = template.replace(pattern, code);
    
            const oldFrame = document.querySelector('.my-frame');
            oldFrame.remove();
    
            const htmlString = '<iframe class="my-frame" width="100%" height="512px" src="about:blank"></iframe>';
            const parser = new DOMParser();
            const doc = parser.parseFromString(htmlString, 'text/html');
            const iframe = doc.querySelector('.my-frame'); 
            const div = document.getElementById('gradioDemoDiv');
            div.appendChild(iframe);
    
            const frame = document.querySelector('.my-frame');
            frame.contentWindow.document.open('text/html', 'replace');
            frame.contentWindow.document.write(completedTemplate);
            frame.contentWindow.document.close();
        }}"""
    elif demo_type == 'stlite':
        return f"""async (code) => {{       
            async function update() {{
                const appController = document.getElementById('demo-iframe').contentWindow.window.appController;
                const newCode = code + ` # Update tag ${{Math.random()}}`;
                const entrypointFile = "streamlit_app.py";
                appController.writeFile(entrypointFile, newCode);
            }};
            await update();
        }}"""
    raise NotImplementedError(f'{demo_type} is not a supported demo type')


def copy_snippet_js(demo_type):
    if demo_type == 'gradio-lite':
        return f"""async (code) => {{
            const pattern = /# APP CODE START(.*?)# APP CODE END/gs;
            const template = `<div id="KiteWindApp">\n<script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.js"></script>
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
            <gradio-lite>\n# APP CODE START\n\n# APP CODE END\n</gradio-lite>\n</div>\n`;
            // Step 1: Generate the HTML content
            const completedTemplate = template.replace(pattern, code);
    
            const snippet = completedTemplate;
            await navigator.clipboard.writeText(snippet);
        }}"""
    elif demo_type == 'stlite':
        return f"""async (code) => {{
            const escapedCode = code.replace('`', String.fromCharCode(92) + '`');
            const template = `{stlite_html_template}`;
            // Step 1: Generate the HTML content
            const completedTemplate = template.replace('STARTING_CODE', code);
            
            const snippet = completedTemplate;            
            await navigator.clipboard.writeText(snippet);
        }}"""
    raise NotImplementedError(f'{demo_type} is not a supported demo type')


def download_code_js(demo_type):
    if demo_type == 'gradio-lite':
        return f"""(code) => {{
            const pattern = /# APP CODE START(.*?)# APP CODE END/gs;
            const template = `{gradio_lite_html_template}`;
            // Step 1: Generate the HTML content
            const completedTemplate = template.replace(pattern, code);
            
            // Step 2: Create a Blob from the HTML content
            const blob = new Blob([completedTemplate], {{ type: "text/html" }});
            
            // Step 3: Create a URL for the Blob
            const url = URL.createObjectURL(blob);
            
            // Step 4: Create a download link
            const downloadLink = document.createElement("a");
            downloadLink.href = url;
            downloadLink.download = "gradio-lite-app.html"; // Specify the filename for the download
            
            // Step 5: Trigger a click event on the download link
            downloadLink.click();
            
            // Clean up by revoking the URL
            URL.revokeObjectURL(url);
        }}"""
    elif demo_type == 'stlite':
        return Path('stlite_starting_code.py').read_text()
    raise NotImplementedError(f'{demo_type} is not a supported demo type')