diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 584cf375b..46f847d1a 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -71,7 +71,7 @@ package. .. 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) diff --git a/sphinx/application.py b/sphinx/application.py index 784e47c8e..d7e0cad4f 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -998,25 +998,36 @@ class Sphinx(object): """ self.registry.add_post_transform(transform) - def add_javascript(self, filename): - # type: (unicode) -> None + def add_javascript(self, filename, **kwargs): + # type: (unicode, **unicode) -> None """Register a JavaScript file to include in the HTML output. Add *filename* to the list of JavaScript files that the default HTML template will include. The filename must be relative to the HTML - static path, see :confval:`the docs for the config value - `. A full URI with scheme, like - ``http://example.org/foo.js``, is also supported. + static path , or a full URI with scheme. The keyword arguments are + also accepted for attributes of `` + + app.add_javascript('example.js', async="async") + # => .. versionadded:: 0.5 + + .. versionchanged:: 1.8 + Allows keyword arguments as attributes of script tag. """ logger.debug('[app] adding javascript: %r', filename) - from sphinx.builders.html import StandaloneHTMLBuilder + from sphinx.builders.html import StandaloneHTMLBuilder, JavaScript if '://' in filename: - StandaloneHTMLBuilder.script_files.append(filename) + js = JavaScript(filename, **kwargs) # type: ignore else: - StandaloneHTMLBuilder.script_files.append( - posixpath.join('_static', filename)) + js = JavaScript(posixpath.join('_static', filename), **kwargs) + + StandaloneHTMLBuilder.script_files.append(js) def add_css_file(self, filename, **kwargs): # type: (unicode, **unicode) -> None diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 90558c0e4..e2860e329 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -139,7 +139,7 @@ class CSSContainer(list): class Stylesheet(text_type): - """The metadata of stylesheet. + """A metadata of stylesheet. To keep compatibility with old themes, an instance of stylesheet behaves as its filename (str). @@ -162,6 +162,26 @@ class Stylesheet(text_type): 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): """buildinfo file manipulator. @@ -1479,6 +1499,31 @@ def convert_html_css_files(app, config): 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 '' % ' '.join(attrs) + + context['js_tag'] = js_tag + + def setup(app): # type: (Sphinx) -> Dict[unicode, Any] # builders @@ -1529,6 +1574,7 @@ def setup(app): # event handlers app.connect('config-inited', convert_html_css_files) + app.connect('html-page-context', setup_js_tag_helper) return { 'version': 'builtin', diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index 4795f7397..04957be2e 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -88,8 +88,8 @@ {%- macro script() %} - {%- for scriptfile in script_files %} - + {%- for js in script_files %} + {{ js_tag(js) }} {%- endfor %} {%- endmacro %}