4

I am trying to use some features of the leaflet.js library in my Python code. And in order to execute JS commands in the code I am using PyV8. But I am unable to load the leaflet.js library into PyV8 context. When I do this,

ctxt.eval(open("leaflet.js").read())

I get the error:

ReferenceError: window is not defined (  @ 9 : 68 )  -> of t.coords[c]&&(u[c]=t.coords[c]);this.fire("locationfound",u)}})}(window,doc

I even tried to load the jquery library before thinking maybe leaflet is dependent on it. But then I get the error,

TypeError: Cannot read property 'defaultView' of undefined (  @ 2 : 68 )  -> :!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultVi

Is there a way I can successfully load JS library?

Michel Müller
  • 5,535
  • 3
  • 31
  • 49
aa8y
  • 3,854
  • 4
  • 37
  • 62

1 Answers1

3

You can only use libraries that are not depending on the DOM, since it is obviously not available server side. One example of such a universally usable library is mustache.js.

Edit: Looks like there is a way, apparently leaflet's can still be useful without the DOM - one simply has to somewhat recreate DOM first, as this nice fellow shows here: https://github.com/rclark/server-side-leaflet. Note: not sure whether this works together with PyV8, you'll have to just try.

Edit2: To extend a little bit on the previous point: What you get with PyV8 is a pure non-browser-based javascript runtime environment. It has no idea about what 'window' or 'document' is, since V8 is not concerned about UI. Leaflet needs the DOM to operate, so it needs to 'think' it lives inside a browser. rclark's server side leaflet needs node.js specific extensions, so it won't work in PyV8.

There's this javascript DOM implementation that might work in PyV8: https://github.com/andreasgal/dom.js/. You'd have to load all the js sources provided there into PyV8 in the right order - note that this library only provides instructions for spidermonkey, not V8. I.e. this is going to be tricky to get right.

So, as I see it you have the following options (in order of increasing complexity and/or skill required):

  1. Someone has apparently solved this problem for python in the following thread, but apparently using some rectangular approximation using OTR - see his github link in the comments to the accepted answer. I'd check this out and decide whether the approximation is good enough. Lookup country for GPS coordinates without Internet access
  2. Switch to a browser based environment and use leaflet directly.
  3. Switch to node.js and use rclark's port.
  4. Try to somehow get a DOM into your PyV8, possibly using andreasgal and then use leaflet from there.
  5. Adapt leaflet for your needs such that it doesn't have any DOM dependencies anymore (start with shielding anything using window and/or document in something like if (typeof(window) === 'object' && window !== null){...}. If you get this working, I'd make a pull request to the leaflet project since many others might profit from your work.
Community
  • 1
  • 1
Michel Müller
  • 5,535
  • 3
  • 31
  • 49
  • Could you please be clearer? Does that mean I cannot load leaflet.js, or is there a way? – aa8y Apr 16 '14 at 06:09
  • Okay, treat me like someone who's new to any kind of web development. The problem I just know basic JS and his instructions don't make sense to me. So can you please elaborate a bit? – aa8y Apr 16 '14 at 18:19
  • Sorry, I've had a closer look at the server-side-github - both it and its dependency, jsdom, require node.js, so they're not compatible with PyV8. In the following SO thread they link to another js-DOM-implementation that you could try to make work together with leaflet: http://stackoverflow.com/questions/9833756/how-to-load-a-nodejs-module-in-pyv8. But I'm afraid this isn't going to be a walk in the park, especially if you don't have solid web developer experience. If I were you I'd look for Python-native implementations of what leaflet does. – Michel Müller Apr 16 '14 at 22:22
  • It's a shame that so many JS libraries are being developed with a dependency on the DOM, even when it's not necessary - this is the main reason why server side javascript is still not a great ecosystem. – Michel Müller Apr 16 '14 at 22:23
  • Btw. another possibility is switching to Node.js if you're not bound to Python somehow. I have to say that PyV8 itself is not very stable, so I'd only use it when really necessary. – Michel Müller Apr 16 '14 at 22:25
  • Thank you for your inputs. The thing I am trying to do is, based on a set of geographical coordinates, decide which country it belongs to. Google has an API which provides this service but it's limited to 2500 queries a day, which I exhaust in 5 minutes. So I am looking for a viable alternative and leaflet did it, though it wasn't straightforward. Any inputs? – aa8y Apr 17 '14 at 00:32