from enum import Enum from pathlib import Path class DemoType(Enum): GRADIO = 1 STREAMLIT = 2 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() gradio_lite_snippet_template = Path('templates/gradio-lite/gradio-lite-snippet-template.html').read_text() stlite_snippet_template = Path('templates/stlite/stlite-snippet-template.html').read_text() def starting_app_code(demo_type: DemoType) -> str: if demo_type == DemoType.GRADIO: return Path('templates/gradio-lite/gradio_lite_starting_code.py').read_text().replace('`', r'\`') elif demo_type == DemoType.STREAMLIT: 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: DemoType) -> str: if demo_type == DemoType.GRADIO: return f"""() => {{ if (window.gradioLiteLoaded) {{ return }} const htmlString = ''; const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, 'text/html'); const iframe = doc.getElementById('gradio-iframe'); const div = document.getElementById('gradioDemoDiv'); div.appendChild(iframe); const template = `{gradio_lite_html_template.replace('STARTING_CODE', starting_app_code(demo_type))}`; const frame = document.getElementById('gradio-iframe'); frame.contentWindow.document.open('text/html', 'replace'); frame.contentWindow.document.write(template); frame.contentWindow.document.close(); window.gradioLiteLoaded = true; }}""" elif demo_type == DemoType.STREAMLIT: return f"""() => {{ if (window.stliteLoaded) {{ return }} const htmlString = ''; const parser = new DOMParser(); const doc = parser.parseFromString(htmlString, 'text/html'); const iframe = doc.getElementById('stlite-iframe'); const div = document.getElementById('stliteDemoDiv'); div.appendChild(iframe); const template = `{stlite_html_template.replace('STARTING_CODE', starting_app_code(demo_type))}`; const frame = document.getElementById('stlite-iframe'); frame.contentWindow.document.open(); frame.contentWindow.document.write(template); frame.contentWindow.document.close(); window.stliteLoaded = true; }}""" raise NotImplementedError(f'{demo_type} is not a supported demo type') def update_iframe_js(demo_type: DemoType) -> str: if demo_type == DemoType.GRADIO: return f"""async (code) => {{ async function update() {{ // Remove existing stylesheet so it will be reloaded; // see https://github.com/gradio-app/gradio/blob/200237d73c169f39514465efc163db756969d3ac/js/app/src/lite/css.ts#L41 const demoFrameWindow = document.getElementById('gradio-iframe').contentWindow; demoFrameWindow.document.querySelector("head style").remove(); const appController = demoFrameWindow.window.appController; const newCode = code + ` # Update tag ${{Math.random()}}`; appController.run_code(newCode); }}; await update(); }}""" elif demo_type == DemoType.STREAMLIT: return f"""async (code) => {{ async function update() {{ const appController = document.getElementById('stlite-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: DemoType) -> str: if demo_type == DemoType.GRADIO: return f"""async (code) => {{ const escapedCode = code.replace('`', String.fromCharCode(92) + '`'); const template = `{gradio_lite_snippet_template}`; // Step 1: Generate the HTML content const completedTemplate = template.replace('STARTING_CODE', code); const snippet = completedTemplate; await navigator.clipboard.writeText(snippet); }}""" elif demo_type == DemoType.STREAMLIT: return f"""async (code) => {{ const escapedCode = code.replace('`', String.fromCharCode(92) + '`'); const template = `{stlite_snippet_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: DemoType) -> str: if demo_type == demo_type.GRADIO: return f"""(code) => {{ const escapedCode = code.replace('`', String.fromCharCode(92) + '`'); // Step 1: Generate the HTML content const completedTemplate = `{gradio_lite_html_template}`.replace('STARTING_CODE', escapedCode); // 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 == demo_type.STREAMLIT: return f"""(code) => {{ const escapedCode = code.replace('`', String.fromCharCode(92) + '`'); // Step 1: Generate the HTML content const completedTemplate = `{stlite_html_template}`.replace('STARTING_CODE', escapedCode); // 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 = "stlite-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); }}""" raise NotImplementedError(f'{demo_type} is not a supported demo type')