Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I load Raphael within IPython notebook, avoiding some issues that arise due to require.js?

In an IPython notebook, one would expect the following code to cause Raphael.js to load successfully into the global namespace.

from IPython.display import Javascript

raphael_url = "https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"
Javascript('alert(Raphael);', lib=[raphael_url])

However, it does not work in recent versions of IPython which use require.js. Turns out, Raphael.js, which IPython loads using jQuery.getScript(), recognizes the presence of require.js and as such does not insert itself into the global namespace. In fact, if one first runs javascript code removing the window.define object, Raphael no longer realizes require.js is present, and it inserts itself into the global namespace as I would like. In other words, the code above works after running the following:

Javascript('window.define = undefined;')

Thus, the only way I am able to get Raphael to load within a recent version of IPython notebook is to delete (or set aside) window.define.

Having identified the problem, I am not familiar enough with require.js to know what piece of software is acting against protocol. Is Raphael using a poor way of testing for the existence of require.js? Should IPython be using require.js directly instead of jQuery.getScript() when it loads user-provided javascript libraries? Or is there a way I as the user ought to be embracing require.js, which will give me the Raphael object without needing any special hacks? (If the answer to the last question is yes, is there a way I can also support older versions of IPython notebook, which do not use require.js?)

like image 780
Jim Garrison Avatar asked Oct 21 '13 05:10

Jim Garrison


1 Answers

The first part of my answer won't please you, but the loading and requirement of javascript library in the IPython-notebook-webapp has not yet been solved, so for now I would suggest not to build to much on the assumption you can load library like that, and rely more on custom.js for now.

That being said, if raphael is not in global namespace require is smart enough to cache it, and give you reference to it. Then in the callback you can just assign to a global :

require(['raphael'], function( raph ){ window.raphael = raph; })

Or something like that should do the trick.

like image 189
Matt Avatar answered Oct 19 '22 11:10

Matt