{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "\n",
    "pn.extension()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `HTML` pane allows rendering arbitrary HTML in a panel. It renders strings containing valid HTML as well as objects with a `_repr_html_` method and may define custom CSS styles.\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n",
    "\n",
    "* **`disable_math`** (boolean, `default=True`): Whether to disable MathJax math rendering for strings escaped with `$$` delimiters.\n",
    "* **`enable_streaming`** (boolean, `default=False`): Whether to enable streaming of text snippets. This will diff the `object` when it is updated and only send the trailing chunk that was added.\n",
    "* **`object`** (str or object): The string or object with ``_repr_html_`` method to display\n",
    "* **`sanitize_html`** (boolean, `default=False`): Whether to sanitize HTML sent to the frontend.\n",
    "* **`sanitize_hook`** (Callable, `default=bleach.clean`): Sanitization callback to apply if `sanitize_html=True`.\n",
    "* **`styles`** (dict): Dictionary specifying CSS styles\n",
    "\n",
    "___"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `HTML` pane accepts the entire HTML5 spec including any embedded script tags, which will be executed. It also supports a `styles` dictionary to apply styles to control the style of the `<div>` tag the HTML contents will be rendered in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "styles = {\n",
    "    'background-color': '#F6F6F6', 'border': '2px solid black',\n",
    "    'border-radius': '5px', 'padding': '10px'\n",
    "}\n",
    "\n",
    "html_pane = pn.pane.HTML(\"\"\"\n",
    "<h1>This is an HTML pane</h1>\n",
    "\n",
    "<code>\n",
    "x = 5;<br>\n",
    "y = 6;<br>\n",
    "z = x + y;\n",
    "</code>\n",
    "\n",
    "<br>\n",
    "<br>\n",
    "\n",
    "<table>\n",
    "  <tr>\n",
    "    <th>Firstname</th>\n",
    "    <th>Lastname</th> \n",
    "    <th>Age</th>\n",
    "  </tr>\n",
    "  <tr>\n",
    "    <td>Jill</td>\n",
    "    <td>Smith</td> \n",
    "    <td>50</td>\n",
    "  </tr>\n",
    "  <tr>\n",
    "    <td>Eve</td>\n",
    "    <td>Jackson</td> \n",
    "    <td>94</td>\n",
    "  </tr>\n",
    "</table>\n",
    "\"\"\", styles=styles)\n",
    "\n",
    "html_pane"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To update the ``object`` or ``styles`` we can simply set it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "html_pane.styles = dict(html_pane.styles, border='2px solid red')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## HTML Documents\r\n",
    "\r\n",
    "The `HTML` pane is designed to display *basic* HTML content. It is not suitable for rendering full HTML documents that include JavaScript or other dynamic elements.\r\n",
    "\r\n",
    "To display complete HTML documents, you can escape the HTML content and embed it within an [`iframe`](https://www.w3schools.com/html/html_iframe.asp). Here's how you can achieve this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import html\n",
    "import hvplot.pandas\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import panel as pn\n",
    "from io import StringIO\n",
    "\n",
    "pn.extension()\n",
    "\n",
    "# Set seed for reproducibility\n",
    "np.random.seed(1)\n",
    "\n",
    "# Create a time-series data frame\n",
    "idx = pd.date_range(\"1/1/2000\", periods=1000)\n",
    "df = pd.DataFrame(np.random.randn(1000, 4), index=idx, columns=list(\"ABCD\")).cumsum()\n",
    "\n",
    "# Plot the data using hvplot\n",
    "plot = df.hvplot()\n",
    "\n",
    "# Save the plot. We use a StringIO object in the reference guide to avoid saving to disk.\n",
    "plot_file = StringIO()\n",
    "hvplot.save(plot, plot_file)\n",
    "plot_file.seek(0)  # Move to the beginning of the StringIO object\n",
    "\n",
    "# Read the HTML content and escape it\n",
    "html_content = plot_file.read()\n",
    "escaped_html = html.escape(html_content)\n",
    "\n",
    "# Create iframe embedding the escaped HTML and display it\n",
    "iframe_html = f'<iframe srcdoc=\"{escaped_html}\" style=\"height:100%; width:100%\" frameborder=\"0\"></iframe>'\n",
    "\n",
    "# Display iframe in a Panel HTML pane\n",
    "pn.pane.HTML(iframe_html, height=350, sizing_mode=\"stretch_width\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This method ensures that the embedded HTML is safely isolated within an iframe, preventing any script execution that might otherwise occur directly within the Panel environment. This approach is particularly useful for embedding rich content, such as interactive visualizations, that requires its own separate HTML structure."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
