Skip to content

Commit

Permalink
Fix Preact app CSS in shadow DOM
Browse files Browse the repository at this point in the history
Since the Preact app has now been moved into a shadow DOM the app's CSS
was no longer working: the `<link>` elements for the app's stylesheets
were outside of the shadow DOM where they don't affect the content
inside the shadow DOM.

The `<link>`'s to the app's stylesheets need to be moved into the shadow
DOM. The problem is that the Preact app renders the contents of the
shadow DOM, but the stylesheet URLs are only available to the Jinja
templates and not available to the Preact app, but the Jinja templates
only render the outer page not the contents of the shadow DOM.

Get around this by having the Jinja templates pass the stylesheet URLs
into the Preact app so that the Preact app can render the `<link>`'s in
the shadow DOM: change the `create.html.jinja2` template to render the
app's stylesheet URLs in a `"js-config"` object instead of actually
rendering them as stylesheet `<link>`'s, then change the Preact app to
read the stylesheet URLs from the `"js-config"` object and to render
`<link>`'s for the stylesheet URLs into the shadow DOM.

This `"js-config"` object can be used more in future when we need the
Python code/Jinja templates to pass more configuration into the Preact
app.
  • Loading branch information
seanh committed Jul 5, 2024
1 parent c0327d8 commit 99ecf14
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
9 changes: 9 additions & 0 deletions h/static/scripts/group-forms/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type ConfigObject = {
/** The URLs of the app's CSS stylesheets. */
styles: string[];
};

/** Return the frontend config from the page's <script class="js-config">. */
export default function readConfig(): ConfigObject {
return JSON.parse(document.querySelector('.js-config')!.textContent!);
}
13 changes: 12 additions & 1 deletion h/static/scripts/group-forms/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import { render } from 'preact';

import CreateGroupForm from './components/CreateGroupForm';
import readConfig from './config';

function init() {
const shadowHost = document.querySelector('#create-group-form')!;
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });
render(<CreateGroupForm />, shadowRoot);
const config = readConfig();
const stylesheetLinks = config.styles.map(stylesheetURL => (
<link rel="stylesheet" href={stylesheetURL} />

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.
));
render(
<>
{stylesheetLinks}
<CreateGroupForm />
</>,
shadowRoot,
);
}

init();
13 changes: 5 additions & 8 deletions h/templates/groups/create.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@

{% set page_title = 'Create a new private group' %}

{% block styles %}
{{ super() }}

{% for url in asset_urls('group_forms_css') %}
<link rel="stylesheet" href="{{ url }}">
{% endfor %}
{% endblock %}

{% block page_content %}
<div id="create-group-form"></div>
<script type="application/json" class="js-config">
{
"styles": {{ asset_urls("group_forms_css")|tojson }}
}
</script>
{% endblock %}

{% block scripts %}
Expand Down

0 comments on commit 99ecf14

Please sign in to comment.