Merge pull request #10018 from tk0miya/10013_add_async_js_file

Close #10013: html: Allow to change the loading method of JavaScript
This commit is contained in:
Takeshi KOMIYA 2021-12-27 02:30:00 +09:00 committed by GitHub
commit a284aa6571
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 2 deletions

View File

@ -26,6 +26,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

View File

@ -930,7 +930,8 @@ class Sphinx:
"""
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
@ -942,6 +943,8 @@ class Sphinx:
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.
@ -951,7 +954,7 @@ class Sphinx:
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';")
@ -980,7 +983,15 @@ class Sphinx:
.. 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

View File

@ -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()