Source code for duck.html.components.style

"""
Style HTML Component.

This module defines a reusable `Style` component for embedding CSS styles within an HTML document.
"""

from duck.html.components import InnerComponent
from duck.csp import csp_nonce, csp_nonce_flag


[docs] class Style(InnerComponent): """ Style HTML Component. The `Style` component allows developers to define and embed custom CSS styles directly within an HTML page. It can be used to dynamically style elements without needing an external stylesheet. **Features:** - Supports inline CSS. - Can be dynamically added to any component. - Enables styling customization for other components. **Example Usage:** ```py style = Style( inner_html=''' .custom-popup { background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px; border-radius: 5px; } ''' ) component.add_child(style) ``` This will generate the following HTML output: ```html <style> .custom-popup { background-color: rgba(0, 0, 0, 0.8); color: white; padding: 10px; border-radius: 5px; } </style> ``` **Notes:** - **Automatic Nonce Addition**: When `ENABLE_HEADERS_SECURITY_POLICY=True` and `csp_nonce_flag` is set in `CSP_TRUSTED_SOURCES`, the `nonce` property is automatically added. - **Request Resolution Required**: For the `nonce` to be set automatically, the request must be resolved. This is achieved by calling `get_request_or_raise` on the component root (or the current component if the root is `None`). - The `inner_html` parameter must contain valid CSS code. - This component is intended for **inline styles** and does not support linking to external CSS files. - Styles defined within this component will apply globally unless scoped using class or ID selectors. """ @property def properties(self): from duck.settings import SETTINGS props = super().properties # Set CSP configuration. if SETTINGS['ENABLE_HEADERS_SECURITY_POLICY']: current_nonce = props.get("nonce") if not current_nonce: self.set_csp_nonce() return props
[docs] def set_csp_nonce(self): """ This tries to retrieve current request nonce. """ from duck.settings import SETTINGS from duck.html.components.extensions import RequestNotFoundError try: root = self.get_raw_root() request = root.get_request_or_raise() except RequestNotFoundError: try: request = self.get_request_or_raise() except RequestNotFoundError: return # Set CSP configuration csp_directives = SETTINGS['CSP_TRUSTED_SOURCES'] if csp_directives and request: style_src = set(csp_directives.get("style-src")) if csp_nonce_flag in style_src: nonce = csp_nonce(request) # Use _get_raw_props instead to avoid recursion if this method is executed # from properties/props property method. self._get_raw_props()["nonce"] = nonce
[docs] def get_element(self): """ Returns the HTML tag for the component. """ return "style"