apneadiving / Google-Maps-for-Rails

Enables easy Google map + overlays creation in Ruby apps
https://apneadiving.github.io/
MIT License
2.26k stars 382 forks source link

Gem turbolinks support #320

Closed framis closed 10 years ago

framis commented 11 years ago

The map does not show when the gem Turbolinks is installed.

http://stackoverflow.com/questions/13807686/gmaps4rails-and-turbolinks-not-loading-without-full-page-refresh

fiedl commented 11 years ago

Since my previous pull request did not solve the problem that maps were not shown when first visiting a page without map and then loading a page with map using turbolinks, I have cancelled my pull request.

Background: Single-origin policy

As I have figured out in the meantime, this was due to javascript's so called single-origin policy. The google api included by the gmap4rails gem requests another script from a google static server. But if the api is dynamically included by turbolinks, the single-origin policy prevents the request to the google static server.

The single-origin policy itself is a useful thing. Although there are a couple of ways to circumvent it, this appears not to be a natural thing to do. Instead, the "right way" to do it is to "prove" that the web page really wants to execute the remote script (the google api) and that the remote script is not requested by a malicious script. This is done by including the script tag that requests the google api directly in the html tree.

Including the google api script tag directly in the html tree is only possible on the first request, when using turbolinks, since all later changes are dynamically injected into the tree by turbolinks. That means that, when using turbolinks, the google api has to be included even on pages that do not show a map.

Fork to solve the problem

I have prepared a fork of the gmaps4rails gem, which tries to accomplish that.

@frenci : Could you test if this fork works for your project, before I start another pull request?

In order to use the fork, you have to do two things:

  1. In your Gemfile, specify my fork as source for gmaps4rails:

    # Gemfile
    gem 'gmaps4rails', '~> 2.0.1', git: 'git@github.com:fiedl/Google-Maps-for-Rails.git'
  2. In your layout file, include the google api in the page header using the gmaps4rails_api_script_tags helper method:

    <!-- app/layouts/default.html.erb -->
    <html><head>
     ...
     <%= gmaps4rails_api_script_tags %>
    </head> ... </html>

Alternative: Load the second script directly

There is an alternative "hack" that solves the problem including the google maps api. But it fixes the google static server to "de_de" or any other locale you choose. Have a look at this gist.

bishisht commented 8 years ago

I did just what you said @fiedl but I am getting an error

Sprockets::FileNotFound at / couldn't find file 'gmaps/google' with type 'application/javascript'

fiedl commented 8 years ago

@bishisht : I've recently reviewed the issue, because it felt wrong to still live with the fork rather than to use the upstream gem.

It surely depends on your use case, but for our limited use it looks like dropping the gem and going with the native gmaps api is worth considering.

Our first experiments suggest there's absolutely no issue with turbolinks when using the gmaps api directly.

If you're interested I'll reference the commit here when pushing it to github.