diff --git a/holoviews/ipython/__init__.py b/holoviews/ipython/__init__.py
index 90264211c4..a92c21af74 100644
--- a/holoviews/ipython/__init__.py
+++ b/holoviews/ipython/__init__.py
@@ -81,7 +81,7 @@ def load_hvjs(logo=False, JS=True, message='HoloViewsJS successfully loaded.'):
"""
# Evaluate load_notebook.html template with widgetjs code
if JS:
- widgetjs, widgetcss = Renderer.embed_assets()
+ widgetjs, widgetcss = Renderer.html_assets(extras=False, backends=[])
else:
widgetjs, widgetcss = '', ''
templateLoader = jinja2.FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))
@@ -165,8 +165,7 @@ def __call__(self, *args, **params):
loaded = ', '.join(js_names[r] if r in js_names else r.capitalize()+'JS'
for r in resources)
- load_hvjs(logo=p.logo,
- JS=('holoviews' in resources),
+ load_hvjs(logo=p.logo, JS=('holoviews' in resources),
message = '%s successfully loaded in this cell.' % loaded)
for r in [r for r in resources if r != 'holoviews']:
Store.renderers[r].load_nb(inline=p.inline)
diff --git a/holoviews/ipython/load_notebook.html b/holoviews/ipython/load_notebook.html
index 12504ffbe0..92139da2b9 100644
--- a/holoviews/ipython/load_notebook.html
+++ b/holoviews/ipython/load_notebook.html
@@ -1,10 +1,6 @@
-
+{{ widgetjs }}
-
+{{ widgetcss }}
{% if logo %}
diff --git a/holoviews/plotting/bokeh/renderer.py b/holoviews/plotting/bokeh/renderer.py
index b581f37785..80d8ef6c47 100644
--- a/holoviews/plotting/bokeh/renderer.py
+++ b/holoviews/plotting/bokeh/renderer.py
@@ -37,9 +37,7 @@ class BokehRenderer(Renderer):
widgets = {'scrubber': BokehScrubberWidget,
'widgets': BokehSelectionWidget}
- js_dependencies = Renderer.js_dependencies + CDN.js_files
-
- css_dependencies = Renderer.css_dependencies + CDN.css_files
+ backend_dependencies = {'js': CDN.js_files, 'css': CDN.css_files}
_loaded = False
diff --git a/holoviews/plotting/renderer.py b/holoviews/plotting/renderer.py
index a4c16dd5ed..c3f648c317 100644
--- a/holoviews/plotting/renderer.py
+++ b/holoviews/plotting/renderer.py
@@ -123,10 +123,16 @@ class Renderer(Exporter):
# Define appropriate widget classes
widgets = {'scrubber': ScrubberWidget, 'widgets': SelectionWidget}
- js_dependencies = ['https://code.jquery.com/jquery-2.1.4.min.js',
- 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.min.js']
+ core_dependencies = {'jQueryUI': {'js': ['https://code.jquery.com/ui/1.10.4/jquery-ui.min.js'],
+ 'css': ['https://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css']}}
- css_dependencies = ['https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css']
+ extra_dependencies = {'jQuery': {'js': ['https://code.jquery.com/jquery-2.1.4.min.js']},
+ 'underscore': {'js': ['https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js']},
+ 'require': {'js': ['https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.20/require.min.js']},
+ 'bootstrap': {'css': ['https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css']}}
+
+ # Any additional JS and CSS dependencies required by a specific backend
+ backend_dependencies = {}
def __init__(self, **params):
super(Renderer, self).__init__(**params)
@@ -238,18 +244,8 @@ def static_html(self, obj, fmt=None, template=None):
supplied format. Allows supplying a template formatting string
with fields to interpolate 'js', 'css' and the main 'html'.
"""
- css_html, js_html = '', ''
- js, css = self.embed_assets()
- for url in self.js_dependencies:
- js_html += '' % url
- js_html += '' % js
-
- for url in self.css_dependencies:
- css_html += '' % url
- css_html += '' % css
-
+ js_html, css_html = self.html_assets()
if template is None: template = static_template
-
html = self.html(obj, fmt)
return template.format(js=js_html, css=css_html, html=html)
@@ -340,10 +336,13 @@ class needed to render it with the current renderer.
@classmethod
- def embed_assets(cls):
+ def html_assets(cls, core=True, extras=True, backends=None):
"""
Returns JS and CSS and for embedding of widgets.
"""
+ if backends is None:
+ backends = [cls.backend] if cls.backend else []
+
# Get all the widgets and find the set of required js widget files
widgets = [wdgt for r in Renderer.__subclasses__()
for wdgt in r.widgets.values()]
@@ -358,7 +357,26 @@ def embed_assets(cls):
if f is not None )
widgetcss = '\n'.join(open(find_file(path, f), 'r').read()
for f in css if f is not None)
- return widgetjs, widgetcss
+
+ dependencies = {}
+ if core:
+ dependencies.update(cls.core_dependencies)
+ if extras:
+ dependencies.update(cls.extra_dependencies)
+ for backend in backends:
+ dependencies['backend'] = Store.renderers[backend].backend_dependencies
+
+ js_html, css_html = '', ''
+ for _, dep in sorted(dependencies.items(), key=lambda x: x[0]):
+ for js in dep.get('js', []):
+ js_html += '\n' % js
+ for css in dep.get('css', []):
+ css_html += '\n' % css
+
+ js_html += '\n' % widgetjs
+ css_html += '\n' % widgetcss
+
+ return js_html, css_html
@classmethod
diff --git a/holoviews/plotting/widgets/jsslider.css b/holoviews/plotting/widgets/jsslider.css
index e6de73dfe1..25b9371e0b 100644
--- a/holoviews/plotting/widgets/jsslider.css
+++ b/holoviews/plotting/widgets/jsslider.css
@@ -11,6 +11,10 @@ form.holoform {
padding: 0.8em;
}
+div.holowidgets {
+ padding-right: 0;
+}
+
div.holoslider {
min-height: 0 !important;
height: 0.8em;
@@ -24,7 +28,7 @@ div.holoformgroup {
div.hologroup {
padding-left: 0;
- padding-right: 0.6em;
+ padding-right: 0;
}
.holoselect {
diff --git a/holoviews/plotting/widgets/jsslider.jinja b/holoviews/plotting/widgets/jsslider.jinja
index 6c61389fb1..b20495b411 100644
--- a/holoviews/plotting/widgets/jsslider.jinja
+++ b/holoviews/plotting/widgets/jsslider.jinja
@@ -24,7 +24,7 @@
{% elif widget_data['type']=='dropdown' %}