Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 224cfab

Browse files
Add logic to enable deferring of script loading in output html
Add logic to automatically defer webpack js files and scripts that Sphinx Bootstrap template adds Add config variable to enable/disable the behavior
1 parent 7592a3e commit 224cfab

5 files changed

Lines changed: 45 additions & 4 deletions

File tree

conf.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@
319319
# This is the file name suffix for HTML files (e.g. ".xhtml").
320320
# html_file_suffix = None
321321

322+
# It True, sets js files from Sphinx & Runestone to be loaded with defer attr
323+
# substantially speeding up page rendering. May cause issues with books that
324+
# have custom directives or raw html that assume jquery or another library
325+
# is loaded before body is parsed.
326+
html_defer_js = True
327+
322328
# Output file base name for HTML help builder.
323329
htmlhelp_basename = "PythonCoursewareProjectdoc"
324330

runestone/__init__.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import os, socket, pkg_resources
3131
import CodeChat.CodeToRest
3232
from sphinx.errors import ExtensionError
33+
from sphinx.builders.html import JavaScript
3334

3435

3536
# TODO: clean up - many of the folders are not needed as the files are imported by webpack
@@ -75,6 +76,26 @@ def runestone_extensions():
7576
modules.insert(0, modules.pop(modules.index("runestone.common")))
7677
return modules
7778

79+
# setup_js_defer(app, pagename, templatexname, context, doctree)
80+
# -----------------------
81+
# Used to inspect js right before it is rendered to page so that
82+
# we can forcibly defer js files or prevent same
83+
def setup_js_defer(app, pagename, templatexname, context, doctree):
84+
def js_defer(script_files):
85+
for js in sorted(script_files):
86+
if app.config.html_defer_js:
87+
# Files added from Runestone should already have defer set - so just add it to sphinx based ones
88+
to_defer = ["_static/jquery.js", "_static/underscore.js","_static/doctools.js"]
89+
if isinstance(js, JavaScript) and js in to_defer:
90+
js.attributes["defer"] = ""
91+
else:
92+
#config flag not set, prevent all deferrals
93+
if isinstance(js, JavaScript):
94+
js.attributes.pop("defer", None)
95+
return ''
96+
97+
context['js_defer'] = js_defer
98+
7899

79100
# setup(app)
80101
# ----------
@@ -94,16 +115,18 @@ def setup(app):
94115

95116
for jsfile in script_files:
96117
try:
97-
app.add_autoversioned_javascript(jsfile)
118+
app.add_autoversioned_javascript(jsfile, defer="")
98119
except ExtensionError:
99-
app.add_js_file(jsfile)
120+
app.add_js_file(jsfile, defer="")
100121
for cssfile in _css_files:
101122
try:
102123
app.add_autoversioned_stylesheet(cssfile)
103124
except ExtensionError:
104125
app.add_css_file(cssfile)
105126

106127
app.config.html_static_path.append("dist/")
128+
app.add_config_value("html_defer_js", False, 'env')
129+
app.connect('html-page-context', setup_js_defer)
107130

108131

109132
def get_master_url():

runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
<!DOCTYPE html>
1717
{%- endblock %}
1818

19+
{%- block scripts %}
20+
{# Override the scripts block from sphinx so we can force loading of jquery/underscore/doctools js files #}
21+
{{ js_defer(script_files) }}
22+
{{ super() }}
23+
{%- endblock %}
24+
1925
{# Sidebar: Rework into our Boostrap nav section. #}
2026
{% macro navBar() %}
2127

runestone/common/project_template/conf.tmpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ html_show_sourcelink = False
275275
# This is the file name suffix for HTML files (e.g. ".xhtml").
276276
#html_file_suffix = None
277277

278+
# It True, sets js files from Sphinx & Runestone to be loaded with defer attr
279+
# substantially speeding up page rendering. May cause issues with books that
280+
# have custom directives or raw html that assume jquery or another library
281+
# is loaded before body is parsed.
282+
html_defer_js = True
283+
278284
# Output file base name for HTML help builder.
279285
htmlhelp_basename = 'PythonCoursewareProjectdoc'
280286

runestone/common/runestonedirective.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ def _add_autoversion(
175175

176176

177177
# Convenience method to call ``add_js_file`` using ``add_autoversion``.
178-
def _add_autoversioned_javascript(self, filename):
179-
return self.add_js_file(self.add_autoversion(filename))
178+
def _add_autoversioned_javascript(self, filename, **kwargs):
179+
return self.add_js_file(self.add_autoversion(filename), **kwargs)
180180

181181

182182
# Convenience method for calling ``add_css_file`` using ``add_autoversion``.

0 commit comments

Comments
 (0)