Skip to content

Commit

Permalink
Close sphinx-doc#10013: html: Allow to change the loading method of J…
Browse files Browse the repository at this point in the history
…avaScript
  • Loading branch information
tk0miya authored and AA-Turner committed Dec 29, 2021
1 parent 4fab09e commit 9614be5
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Expand Up @@ -64,6 +64,8 @@ Features added
* #9800: extlinks: Emit warning if a hardcoded link is replaceable
by an extlink, suggesting a replacement.
* #9961: html: Support nested <kbd> HTML elements in other HTML builders
* #10013: html: Allow to change the loading method of JS via ``loading_method``
parameter for :meth:`Sphinx.add_js_file()`
* #9815: html theme: Wrap sidebar components in div to allow customizing their
layout via CSS
* #9899: py domain: Allows to specify cross-reference specifier (``.`` and
Expand Down
15 changes: 13 additions & 2 deletions sphinx/application.py
Expand Up @@ -930,7 +930,8 @@ def add_post_transform(self, transform: Type[Transform]) -> None:
"""
self.registry.add_post_transform(transform)

def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None:
def add_js_file(self, filename: str, priority: int = 500,
loading_method: Optional[str] = None, **kwargs: Any) -> None:
"""Register a JavaScript file to include in the HTML output.
:param filename: The filename of the JavaScript file. It must be relative to the HTML
Expand All @@ -942,6 +943,8 @@ def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None
files" below. If the priority of the JavaScript files it the same
as others, the JavaScript files will be loaded in order of
registration.
:param loading_method: The loading method of the JavaScript file. ``'async'`` or
``'defer'`` is allowed.
:param kwargs: Extra keyword arguments are included as attributes of the ``<script>``
tag. A special keyword argument ``body`` is given, its value will be
added between the ``<script>`` tag.
Expand All @@ -951,7 +954,7 @@ def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None
app.add_js_file('example.js')
# => <script src="_static/example.js"></script>
app.add_js_file('example.js', async="async")
app.add_js_file('example.js', loading_method="async")
# => <script src="_static/example.js" async="async"></script>
app.add_js_file(None, body="var myVariable = 'foo';")
Expand Down Expand Up @@ -980,7 +983,15 @@ def add_js_file(self, filename: str, priority: int = 500, **kwargs: Any) -> None
.. versionchanged:: 3.5
Take priority argument. Allow to add a JavaScript file to the specific page.
.. versionchanged:: 4.4
Take loading_method argument. Allow to change the loading method of the
JavaScript file.
"""
if loading_method == 'async':
kwargs['async'] = 'async'
elif loading_method == 'defer':
kwargs['defer'] = 'defer'

self.registry.add_js_file(filename, priority=priority, **kwargs)
if hasattr(self.builder, 'add_js_file'):
self.builder.add_js_file(filename, priority=priority, **kwargs) # type: ignore
Expand Down
14 changes: 14 additions & 0 deletions tests/test_build_html.py
Expand Up @@ -1195,6 +1195,20 @@ def test_assets_order(app):
assert re.search(pattern, content, re.S)


@pytest.mark.sphinx('html', testroot='html_assets')
def test_javscript_loading_method(app):
app.add_js_file('normal.js')
app.add_js_file('early.js', loading_method='async')
app.add_js_file('late.js', loading_method='defer')

app.builder.build_all()
content = (app.outdir / 'index.html').read_text()

assert '<script src="_static/normal.js"></script>' in content
assert '<script async="async" src="_static/early.js"></script>' in content
assert '<script defer="defer" src="_static/late.js"></script>' in content


@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_copy_source': False})
def test_html_copy_source(app):
app.builder.build_all()
Expand Down

0 comments on commit 9614be5

Please sign in to comment.