Source code for duck.html.components.script
"""
Script HTML Component.
This module defines a reusable `Script` component for embedding JavaScript code within an HTML document.
"""
from duck.html.components import InnerComponent
from duck.csp import csp_nonce, csp_nonce_flag
[docs]
class Script(InnerComponent):
"""
Script HTML Component.
The `Script` component allows developers to embed JavaScript code within an HTML page dynamically.
It can be used to define inline scripts that interact with other components.
**Features:**
- Supports inline JavaScript execution.
- Can be dynamically added to any component.
- Provides flexibility for defining custom client-side logic.
**Example Usage:**
```py
script = Script(
inner_html='''
function showAlert() {
alert("Hello, world!");
}
'''
)
component.add_child(script)
```
This will generate the following HTML output:
```html
<script>
function showAlert() {
alert("Hello, world!");
}
</script>
```
**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`).
"""
@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:
script_src = set(csp_directives.get("script-src"))
if csp_nonce_flag in script_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 "script"