add_javascript() allows keyword arguments as attributes for <script> tag

This commit is contained in:
Takeshi KOMIYA 2018-04-22 13:38:27 +09:00
parent 157619c4e3
commit 8fd34b88d3
4 changed files with 70 additions and 13 deletions

View File

@ -71,7 +71,7 @@ package.
.. automethod:: Sphinx.add_post_transform(transform) .. automethod:: Sphinx.add_post_transform(transform)
.. automethod:: Sphinx.add_javascript(filename) .. automethod:: Sphinx.add_javascript(filename, **kwargs)
.. automethod:: Sphinx.add_stylesheet(filename, alternate=None, title=None) .. automethod:: Sphinx.add_stylesheet(filename, alternate=None, title=None)

View File

@ -998,25 +998,36 @@ class Sphinx(object):
""" """
self.registry.add_post_transform(transform) self.registry.add_post_transform(transform)
def add_javascript(self, filename): def add_javascript(self, filename, **kwargs):
# type: (unicode) -> None # type: (unicode, **unicode) -> None
"""Register a JavaScript file to include in the HTML output. """Register a JavaScript file to include in the HTML output.
Add *filename* to the list of JavaScript files that the default HTML Add *filename* to the list of JavaScript files that the default HTML
template will include. The filename must be relative to the HTML template will include. The filename must be relative to the HTML
static path, see :confval:`the docs for the config value static path , or a full URI with scheme. The keyword arguments are
<html_static_path>`. A full URI with scheme, like also accepted for attributes of ``<script>`` tag.
``http://example.org/foo.js``, is also supported.
Example::
app.add_javascript('example.js')
# => <scrtipt src="_static/example.js"></script>
app.add_javascript('example.js', async="async")
# => <scrtipt src="_static/example.js" async="async"></script>
.. versionadded:: 0.5 .. versionadded:: 0.5
.. versionchanged:: 1.8
Allows keyword arguments as attributes of script tag.
""" """
logger.debug('[app] adding javascript: %r', filename) logger.debug('[app] adding javascript: %r', filename)
from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.builders.html import StandaloneHTMLBuilder, JavaScript
if '://' in filename: if '://' in filename:
StandaloneHTMLBuilder.script_files.append(filename) js = JavaScript(filename, **kwargs) # type: ignore
else: else:
StandaloneHTMLBuilder.script_files.append( js = JavaScript(posixpath.join('_static', filename), **kwargs)
posixpath.join('_static', filename))
StandaloneHTMLBuilder.script_files.append(js)
def add_css_file(self, filename, **kwargs): def add_css_file(self, filename, **kwargs):
# type: (unicode, **unicode) -> None # type: (unicode, **unicode) -> None

View File

@ -139,7 +139,7 @@ class CSSContainer(list):
class Stylesheet(text_type): class Stylesheet(text_type):
"""The metadata of stylesheet. """A metadata of stylesheet.
To keep compatibility with old themes, an instance of stylesheet behaves as To keep compatibility with old themes, an instance of stylesheet behaves as
its filename (str). its filename (str).
@ -162,6 +162,26 @@ class Stylesheet(text_type):
return self return self
class JavaScript(text_type):
"""A metadata of javascript file.
To keep compatibility with old themes, an instance of javascript behaves as
its filename (str).
"""
attributes = None # type: Dict[unicode, unicode]
filename = None # type: unicode
def __new__(cls, filename, **attributes):
# type: (unicode, **unicode) -> None
self = text_type.__new__(cls, filename) # type: ignore
self.filename = filename
self.attributes = attributes
self.attributes.setdefault('type', 'text/javascript')
return self
class BuildInfo(object): class BuildInfo(object):
"""buildinfo file manipulator. """buildinfo file manipulator.
@ -1479,6 +1499,31 @@ def convert_html_css_files(app, config):
config.html_css_files = html_css_files # type: ignore config.html_css_files = html_css_files # type: ignore
def setup_js_tag_helper(app, pagename, templatexname, context, doctree):
# type: (Sphinx, unicode, unicode, Dict, nodes.Node) -> None
"""Set up js_tag() template helper.
.. note:: This set up function is added to keep compatibility with webhelper.
"""
pathto = context.get('pathto')
def js_tag(js):
# type: (JavaScript) -> unicode
attrs = []
if isinstance(js, JavaScript):
for key in sorted(js.attributes):
value = js.attributes[key]
if value is not None:
attrs.append('%s="%s"' % (key, htmlescape(value, True)))
attrs.append('src="%s"' % pathto(js.filename, resource=True))
else:
# str value (old styled)
attrs.append('src="%s"' % pathto(js, resource=True))
return '<script %s></script>' % ' '.join(attrs)
context['js_tag'] = js_tag
def setup(app): def setup(app):
# type: (Sphinx) -> Dict[unicode, Any] # type: (Sphinx) -> Dict[unicode, Any]
# builders # builders
@ -1529,6 +1574,7 @@ def setup(app):
# event handlers # event handlers
app.connect('config-inited', convert_html_css_files) app.connect('config-inited', convert_html_css_files)
app.connect('html-page-context', setup_js_tag_helper)
return { return {
'version': 'builtin', 'version': 'builtin',

View File

@ -88,8 +88,8 @@
{%- macro script() %} {%- macro script() %}
<script type="text/javascript" id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script> <script type="text/javascript" id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
{%- for scriptfile in script_files %} {%- for js in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script> {{ js_tag(js) }}
{%- endfor %} {%- endfor %}
{%- endmacro %} {%- endmacro %}