Skip to content

Commit 39aab2a

Browse files
Carreaugabalafou
andauthored
Maint: do not use document.write (#1921)
Co-authored-by: gabalafou <[email protected]>
1 parent 65d65ef commit 39aab2a

10 files changed

+84
-102
lines changed

src/pydata_sphinx_theme/theme/pydata_sphinx_theme/components/navbar-logo.html

+5-4
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,17 @@
1919
{# use alt_text if given. If not, only add alt text if no additional branding text given. #}
2020
{% set alt = theme_logo.get("alt_text", "" if theme_logo.get("text") else "%s - Home" % docstitle) %}
2121
{% if is_logo %}
22-
{# Theme switching is only available when JavaScript is enabled.
23-
# Thus we should add the extra image using JavaScript, defaulting
24-
# depending on the value of default_mode; and light if unset.
22+
{#
23+
Theme switching is only available when JavaScript is enabled.
24+
We thus adds elements that should be present only when javscipt is
25+
enabled with a pst-js-only class
2526
#}
2627
{% if default_mode is undefined or default_mode == "auto" %}
2728
{% set default_mode = "light" %}
2829
{% endif %}
2930
{% set js_mode = "light" if default_mode == "dark" else "dark" %}
3031
<img src="{{ theme_logo['image_relative'][default_mode] }}" class="logo__image only-{{ default_mode }}" alt="{{ alt }}"/>
31-
<script>document.write(`<img src="{{ theme_logo['image_relative'][js_mode] }}" class="logo__image only-{{ js_mode }}" alt="{{ alt }}"/>`);</script>
32+
<img src="{{ theme_logo['image_relative'][js_mode] }}" class="logo__image only-{{ js_mode }} pst-js-only" alt="{{ alt }}"/>
3233
{% endif %}
3334
{% if not is_logo or theme_logo.get("text") %}
3435
<p class="title logo__title">{{ theme_logo.get("text") or docstitle }}</p>
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
{# Displays a search field image that opens a search overlay when clicked. #}
2-
{# As this function will only work when JavaScript is enabled, we add it through JavaScript. #}
3-
<script>
4-
document.write(`
5-
<button class="btn search-button-field search-button__button" title="{{ _('Search') }}" aria-label="{{ _('Search') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
6-
<i class="fa-solid fa-magnifying-glass"></i>
7-
<span class="search-button__default-text">{{ _('Search') }}</span>
8-
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
9-
</button>
10-
`);
11-
</script>
2+
{#
3+
As this function will only work when JavaScript is enabled,
4+
we add a class that will hide it if js is disable.
5+
#}
6+
<button class="btn search-button-field search-button__button pst-js-only" title="{{ _('Search') }}" aria-label="{{ _('Search') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
7+
<i class="fa-solid fa-magnifying-glass"></i>
8+
<span class="search-button__default-text">{{ _('Search') }}</span>
9+
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
10+
</button>
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
{# Displays a magnifying glass icon that opens a search overlay when clicked. #}
2-
{# As this function will only work when JavaScript is enabled, we add it through JavaScript. #}
3-
<script>
4-
document.write(`
5-
<button class="btn btn-sm pst-navbar-icon search-button search-button__button" title="{{ _('Search') }}" aria-label="{{ _('Search') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
2+
{# As this function will only work when JavaScript is enabled, we hide it with pst-js-only #}
3+
<button class="btn btn-sm pst-navbar-icon search-button search-button__button pst-js-only" title="{{ _('Search') }}" aria-label="{{ _('Search') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
64
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
7-
</button>
5+
</button>
86
`);
9-
</script>
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
{# Displays an icon to switch between light mode, dark mode, and auto (use browser's setting). #}
2-
{# As the theme switcher will only work when JavaScript is enabled, we add it through JavaScript. #}
3-
<script>
4-
document.write(`
5-
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button" title="{{ _('light/dark') }}" aria-label="{{ _('light/dark') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
6-
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
7-
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
8-
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
9-
</button>
10-
`);
11-
</script>
2+
{# As the theme switcher will only work when JavaScript is enabled, we hide it with `pst-js-only`. #}
3+
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" title="{{ _('light/dark') }}" aria-label="{{ _('light/dark') }}" data-bs-placement="bottom" data-bs-toggle="tooltip">
4+
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
5+
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
6+
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
7+
</button>
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
{# Displays a dropdown box for switching among different versions of your documentation. #}
22
{%- set button_id = unique_html_id("pst-version-switcher-button") -%}
33
{%- set dropdown_id = unique_html_id("pst-version-switcher-list") -%}
4-
{# As the version switcher will only work when JavaScript is enabled, we add it through JavaScript. #}
5-
<script>
6-
document.write(`
7-
<div class="version-switcher__container dropdown">
8-
<button id="{{ button_id }}"
9-
type="button"
10-
class="version-switcher__button btn btn-sm dropdown-toggle"
11-
data-bs-toggle="dropdown"
12-
aria-haspopup="listbox"
13-
aria-controls="{{ dropdown_id }}"
14-
aria-label="Version switcher list"
15-
>
16-
Choose version <!-- this text may get changed later by javascript -->
17-
<span class="caret"></span>
18-
</button>
19-
<div id="{{ dropdown_id }}"
20-
class="version-switcher__menu dropdown-menu list-group-flush py-0"
21-
role="listbox" aria-labelledby="{{ button_id }}">
22-
<!-- dropdown will be populated by javascript on page load -->
23-
</div>
4+
{# As the version switcher will only work when JavaScript is enabled, we hide it with pst-js-only #}
5+
<div class="version-switcher__container dropdown pst-js-only">
6+
<button id="{{ button_id }}"
7+
type="button"
8+
class="version-switcher__button btn btn-sm dropdown-toggle"
9+
data-bs-toggle="dropdown"
10+
aria-haspopup="listbox"
11+
aria-controls="{{ dropdown_id }}"
12+
aria-label="Version switcher list"
13+
>
14+
Choose version <!-- this text may get changed later by javascript -->
15+
<span class="caret"></span>
16+
</button>
17+
<div id="{{ dropdown_id }}"
18+
class="version-switcher__menu dropdown-menu list-group-flush py-0"
19+
role="listbox" aria-labelledby="{{ button_id }}">
20+
<!-- dropdown will be populated by javascript on page load -->
2421
</div>
25-
`);
26-
</script>
22+
</div>

src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html

+9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
document.documentElement.dataset.mode = localStorage.getItem("mode") || "{{ default_mode }}";
1818
document.documentElement.dataset.theme = localStorage.getItem("theme") || "{{ default_mode }}";
1919
</script>
20+
<!--
21+
this give us a css class that will be invisible only if js is disabled
22+
-->
23+
<noscript>
24+
<style>
25+
.pst-js-only { display: none !important; }
26+
27+
</style>
28+
</noscript>
2029
{{ _webpack.head_pre_assets() }}
2130
{{ _webpack.head_pre_icons() }}
2231
{{- css() }}

tests/test_build.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def test_primary_logo_is_light_when_no_default_mode(sphinx_build_factory) -> Non
184184
index_html = sphinx_build.html_tree("index.html")
185185
navbar_brand = index_html.select(".navbar-brand")[0]
186186
assert navbar_brand.find("img", class_="only-light") is not None
187-
assert navbar_brand.find("script", string=re.compile("only-dark")) is not None
187+
assert navbar_brand.find("img", class_="only-dark") is not None
188188

189189

190190
def test_primary_logo_is_light_when_default_mode_is_set_to_auto(
@@ -199,7 +199,7 @@ def test_primary_logo_is_light_when_default_mode_is_set_to_auto(
199199
index_html = sphinx_build.html_tree("index.html")
200200
navbar_brand = index_html.select(".navbar-brand")[0]
201201
assert navbar_brand.find("img", class_="only-light") is not None
202-
assert navbar_brand.find("script", string=re.compile("only-dark")) is not None
202+
assert navbar_brand.find("img", class_="only-dark") is not None
203203

204204

205205
def test_primary_logo_is_light_when_default_mode_is_light(sphinx_build_factory) -> None:
@@ -212,7 +212,7 @@ def test_primary_logo_is_light_when_default_mode_is_light(sphinx_build_factory)
212212
index_html = sphinx_build.html_tree("index.html")
213213
navbar_brand = index_html.select(".navbar-brand")[0]
214214
assert navbar_brand.find("img", class_="only-light") is not None
215-
assert navbar_brand.find("script", string=re.compile("only-dark")) is not None
215+
assert navbar_brand.find("img", class_="only-dark") is not None
216216

217217

218218
def test_primary_logo_is_dark_when_default_mode_is_dark(sphinx_build_factory) -> None:
@@ -225,7 +225,7 @@ def test_primary_logo_is_dark_when_default_mode_is_dark(sphinx_build_factory) ->
225225
index_html = sphinx_build.html_tree("index.html")
226226
navbar_brand = index_html.select(".navbar-brand")[0]
227227
assert navbar_brand.find("img", class_="only-dark") is not None
228-
assert navbar_brand.find("script", string=re.compile("only-light")) is not None
228+
assert navbar_brand.find("img", class_="only-light") is not None
229229

230230

231231
def test_logo_missing_image(sphinx_build_factory) -> None:
@@ -805,8 +805,9 @@ def test_version_switcher_error_states(
805805
if url == "switcher.json": # this should work
806806
index = sphinx_build.html_tree("index.html")
807807
switcher = index.select(".navbar-header-items")[0].find(
808-
"script", string=re.compile(".version-switcher__container")
808+
"div", class_="version-switcher__container"
809809
)
810+
assert switcher is not None
810811
file_regression.check(
811812
switcher.prettify(), basename="navbar_switcher", extension=".html"
812813
)
@@ -826,11 +827,7 @@ def test_version_switcher_error_states(
826827
def test_theme_switcher(sphinx_build_factory, file_regression) -> None:
827828
"""Regression test for the theme switcher button."""
828829
sphinx_build = sphinx_build_factory("base").build()
829-
switcher = (
830-
sphinx_build.html_tree("index.html")
831-
.find(string=re.compile("theme-switch-button"))
832-
.find_parent("script")
833-
)
830+
switcher = sphinx_build.html_tree("index.html").find(class_="theme-switch-button")
834831
file_regression.check(
835832
switcher.prettify(), basename="navbar_theme", extension=".html"
836833
)

tests/test_build/navbar_switcher.html

+11-22
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
<script>
2-
document.write(`
3-
<div class="version-switcher__container dropdown">
4-
<button id="pst-version-switcher-button-2"
5-
type="button"
6-
class="version-switcher__button btn btn-sm dropdown-toggle"
7-
data-bs-toggle="dropdown"
8-
aria-haspopup="listbox"
9-
aria-controls="pst-version-switcher-list-2"
10-
aria-label="Version switcher list"
11-
>
12-
Choose version <!-- this text may get changed later by javascript -->
13-
<span class="caret"></span>
14-
</button>
15-
<div id="pst-version-switcher-list-2"
16-
class="version-switcher__menu dropdown-menu list-group-flush py-0"
17-
role="listbox" aria-labelledby="pst-version-switcher-button-2">
18-
<!-- dropdown will be populated by javascript on page load -->
19-
</div>
20-
</div>
21-
`);
22-
</script>
1+
<div class="version-switcher__container dropdown pst-js-only">
2+
<button aria-controls="pst-version-switcher-list-2" aria-haspopup="listbox" aria-label="Version switcher list" class="version-switcher__button btn btn-sm dropdown-toggle" data-bs-toggle="dropdown" id="pst-version-switcher-button-2" type="button">
3+
Choose version
4+
<!-- this text may get changed later by javascript -->
5+
<span class="caret">
6+
</span>
7+
</button>
8+
<div aria-labelledby="pst-version-switcher-button-2" class="version-switcher__menu dropdown-menu list-group-flush py-0" id="pst-version-switcher-list-2" role="listbox">
9+
<!-- dropdown will be populated by javascript on page load -->
10+
</div>
11+
</div>

tests/test_build/navbar_theme.html

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
<script>
2-
document.write(`
3-
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
4-
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
5-
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
6-
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
7-
</button>
8-
`);
9-
</script>
1+
<button aria-label="light/dark" class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" data-bs-placement="bottom" data-bs-toggle="tooltip" title="light/dark">
2+
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light">
3+
</i>
4+
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark">
5+
</i>
6+
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto">
7+
</i>
8+
</button>

tests/test_build/sidebar_subpage.html

+8-9
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@
3333
</div>
3434
<div class="sidebar-header-items__end">
3535
<div class="navbar-item">
36-
<script>
37-
document.write(`
38-
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
39-
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
40-
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
41-
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
42-
</button>
43-
`);
44-
</script>
36+
<button aria-label="light/dark" class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" data-bs-placement="bottom" data-bs-toggle="tooltip" title="light/dark">
37+
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light">
38+
</i>
39+
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark">
40+
</i>
41+
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto">
42+
</i>
43+
</button>
4544
</div>
4645
</div>
4746
</div>

0 commit comments

Comments
 (0)