kosiew opened a new issue, #1171:
URL: https://github.com/apache/datafusion-python/issues/1171

   ## Description:
   
   Currently, DataFrameHtmlFormatter tracks a _styles_loaded class flag in 
Python to avoid re-injecting styles and scripts across notebook cells. However, 
this approach:
   
   - Doesn’t survive module reloads or redefinitions
   - Can conflict if multiple notebooks share the same kernel
   - Still requires manual state resets in tests
   
   We should move the “only-once” guard into the browser DOM/JS layer so that 
every call to format_html can blindly emit the header scripts/styles, but the 
browser will insert them only once per page.
   
   
   ## Proposed Change:
   
   1. Remove the _styles_loaded class variable and related Python guard logic.
   2. Always call _build_html_header() and _get_javascript() on each 
format_html.
   3. Inside those methods, wrap the CSS/JS in small <script> blocks that:
   - Check document.getElementById('df-styles') (or a global flag) before 
appending a <style> tag
   - Check a window.__df_formatter_js_loaded__ flag before defining the toggle 
function
   
   ### example snippet:
   ```python
   --- a/python/datafusion/dataframe_formatter.py
   +++ b/python/datafusion/dataframe_formatter.py
   @@ -XXX,XX +XXX,XX @@ class DataFrameHtmlFormatter:
   -    # Class var: _styles_loaded = False
   
        def _build_html_header(self) -> list[str]:
   -        html = []
   -        # Only include styles and scripts if needed
   -        if include_styles:
   -            html.extend(self._build_css_and_script())
   -            if self.use_shared_styles:
   -                DataFrameHtmlFormatter._styles_loaded = True
   -        return html
   +        return ["""
   <script>
   // Only inject CSS once per page
   if (!document.getElementById('df-styles')) {
     const style = document.createElement('style');
     style.id = 'df-styles';
     style.textContent = `
       /* DataFrameHtmlFormatter CSS… */
     `;
     document.head.appendChild(style);
   }
   </script>
   """] + ([f"<style>{self.custom_css}</style>"] if self.custom_css else [])
   
        def _get_javascript(self) -> str:
   -        return """
   -<script> …existing JS… </script>
   -"""
   +        return """
   <script>
   // Only inject toggle logic once
   if (!window.__df_formatter_js_loaded__) {
     window.__df_formatter_js_loaded__ = true;
     window.toggleDataFrameCellText = function(table_uuid, row, col) {
       /* …existing toggle logic… */
     };
   }
   </script>
   """
   ```
   
   ## Benefits:
   - Guaranteed “inject once” directly in the browser, regardless of Python 
reloads
   - Simplifies Python state—no _styles_loaded flag to manage
   - Safe in multi-notebook or testing scenarios


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to