@@ -147,6 +147,13 @@ def assert_offline(html):
147147 assert get_plotlyjs () in html
148148
149149
150+ def assert_requirejs_workaround (html ):
151+ # nbviewer runs RequireJS; ensure we include the guard that prevents plotly.js
152+ # from registering as an anonymous AMD module (which would leave `Plotly`
153+ # undefined in the output).
154+ assert "__PLOTLY_PY_REQUIREJS_BACKUP__" in html
155+
156+
150157def test_colab_renderer_show (fig1 ):
151158 pio .renderers .default = "colab"
152159
@@ -164,6 +171,7 @@ def test_colab_renderer_show(fig1):
164171 html = mock_arg1 ["text/html" ]
165172 assert_full_html (html )
166173 assert_html_renderer_connected (html )
174+ assert_requirejs_workaround (html )
167175
168176 # check kwargs
169177 mock_kwargs = mock_call_args [1 ]
@@ -191,7 +199,8 @@ def test_notebook_connected_show(fig1, name, connected):
191199 # Check init display contents
192200 bundle_display_html = mock_arg1_html
193201 if connected :
194- assert_html_renderer_connected (bundle_display_html )
202+ assert "window.PlotlyConfig" in bundle_display_html
203+ assert get_plotlyjs () not in bundle_display_html
195204 else :
196205 assert_offline (bundle_display_html )
197206
@@ -206,6 +215,9 @@ def test_notebook_connected_show(fig1, name, connected):
206215 # Check html display contents
207216 bundle_html = mock_arg1 ["text/html" ]
208217 assert_not_full_html (bundle_html )
218+ if connected :
219+ assert_html_renderer_connected (bundle_html )
220+ assert_requirejs_workaround (bundle_html )
209221
210222 # check kwargs
211223 mock_kwargs = mock_call_args [1 ]
@@ -305,22 +317,60 @@ def test_repr_html(renderer):
305317 plotlyjs_content = get_plotlyjs ()
306318 sri_hash = _generate_sri_hash (plotlyjs_content )
307319
320+ requirejs_workaround_pre = (
321+ '<script type="text/javascript">window.__PLOTLY_PY_REQUIREJS_BACKUP__ = '
322+ "window.__PLOTLY_PY_REQUIREJS_BACKUP__ || [];"
323+ "window.__PLOTLY_PY_REQUIREJS_BACKUP__.push({ has_define: typeof "
324+ 'window.define === "function", has_define_amd: typeof window.define === '
325+ '"function" && Object.prototype.hasOwnProperty.call(window.define, "amd"), '
326+ 'define_amd: typeof window.define === "function" ? window.define.amd : '
327+ "undefined, has_module: Object.prototype.hasOwnProperty.call(window, "
328+ '"module"), module: window.module, has_exports: '
329+ 'Object.prototype.hasOwnProperty.call(window, "exports"), exports: '
330+ 'window.exports});/*nbviewer loads RequireJS; plotly.js may register as an '
331+ 'anonymous AMD module, triggering"Mismatched anonymous define()" and leaving '
332+ "`Plotly` undefined. Temporarily disableAMD/CommonJS detection while loading "
333+ 'plotly.js from the CDN.*/if (typeof window.define === "function" && '
334+ "window.define.amd) { window.define.amd = undefined;}if (typeof "
335+ 'window.module === "object" && window.module && window.module.exports) { '
336+ "window.module = undefined;}if (typeof window.exports === \" object\" ) { "
337+ "window.exports = undefined;} </script>\n "
338+ )
339+
340+ requirejs_workaround_post = (
341+ '<script type="text/javascript">(function() { var backups = '
342+ "window.__PLOTLY_PY_REQUIREJS_BACKUP__; if (!backups || !backups.length) "
343+ "{ return; } var b = backups.pop(); if (b.has_define) { "
344+ "if (b.has_define_amd) { window.define.amd = b.define_amd; } "
345+ "else { try { delete window.define.amd; } catch (e) { "
346+ "window.define.amd = undefined; } } } if (b.has_module) { "
347+ "window.module = b.module; } else { try { delete window.module; } "
348+ "catch (e) { window.module = undefined; } } if (b.has_exports) { "
349+ "window.exports = b.exports; } else { try { delete window.exports; } "
350+ "catch (e) { window.exports = undefined; } } if (!backups.length) { "
351+ "try { delete window.__PLOTLY_PY_REQUIREJS_BACKUP__; } catch (e) { "
352+ "window.__PLOTLY_PY_REQUIREJS_BACKUP__ = undefined; } }})(); </script>"
353+ )
354+
308355 template = (
309356 '<div> <script type="text/javascript">'
310- "window.PlotlyConfig = {MathJaxConfig: 'local'};</script>\n "
311- '<script charset="utf-8" src="'
357+ + "window.PlotlyConfig = {MathJaxConfig: 'local'};</script>\n "
358+ + requirejs_workaround_pre
359+ + '<script charset="utf-8" src="'
312360 + plotly_cdn_url ()
313361 + '" integrity="'
314362 + sri_hash
315- + '" crossorigin="anonymous"></script> '
316- '<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
317- 'style="height:100%; width:100%;"></div> <script type="text/javascript">'
318- " window.PLOTLYENV=window.PLOTLYENV || {};"
319- ' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
320- ' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
321- ' [], {"template":{}},'
322- ' {"responsive": true} ) };'
323- " </script> </div>"
363+ + '" crossorigin="anonymous"></script> '
364+ + requirejs_workaround_post
365+ + " "
366+ + '<div id="cd462b94-79ce-42a2-887f-2650a761a144" class="plotly-graph-div" '
367+ + 'style="height:100%; width:100%;"></div> <script type="text/javascript">'
368+ + " window.PLOTLYENV=window.PLOTLYENV || {};"
369+ + ' if (document.getElementById("cd462b94-79ce-42a2-887f-2650a761a144"))'
370+ + ' { Plotly.newPlot( "cd462b94-79ce-42a2-887f-2650a761a144",'
371+ + ' [], {"template":{}},'
372+ + ' {"responsive": true} ) };'
373+ + " </script> </div>"
324374 )
325375 if "text/html" in bundle :
326376 str_bundle = bundle ["text/html" ]
0 commit comments