-1

Nothing I've tried seems to work. I found these two links and thought they'd be helpful, but that hasn't worked either. Dynamically load JavaScript with JavaScript https://developers.google.com/loader/

Here's roughly what my Greasemonkey script looks like currently:

var init_map = function() {
    new google.maps.Geocoder().geocode({address:'1125 NW 12th Ave, Portland, OR'},function(result){
        alert(result);
    });
}

function loadMaps() {
    GM_log("loadMaps called");
    google.load("maps", "3", {"callback" : init_map, "other_params":"key=foo&sensor=false"});
}

function loadScript(filename,callback){
  var fileref=document.createElement('script');
  fileref.setAttribute("type","text/javascript");
  fileref.onload = callback;
  fileref.setAttribute("src", filename);
  if (typeof fileref!="undefined"){
    document.getElementsByTagName("head")[0].appendChild(fileref);
  }
}

$(document).ready(
    function() {
        GM_log("document ready");
        loadScript('http://www.google.com/jsapi?key=ABQIAAAAfoo',function(){
            loadMaps();
        });
    }
);

I've found that if I don't include // @require http://www.google.com/jsapi?key=ABQIAAAAfoo in the Greasemonkey script, I get a google is undefined error. If I do include it, init_map() never gets called. Any suggestions?

Community
  • 1
  • 1
Pratik
  • 378
  • 3
  • 14
  • possible duplicate of http://stackoverflow.com/questions/7894996/how-to-use-the-google-maps-api-with-greasemonkey-to-read-a-table-of-addresses-an – RASG Apr 05 '12 at 17:32

3 Answers3

2

var init_map defines a local variable in the GreaseMonkey context.

If you want to run JavaScript in the context of a webpage, I recommend to inject two <script> tags in the web page (another method is to prefix all of your global variables with unsafeWindow.):

  1. Google's map API
  2. Your script.

Example:

// ==UserScript==
// @name           Name of script
// @namespace      YourNameSpaceHere
// @match          http://blabla.com/*
// @version        1.0
// @run-at         document-end
// ==/UserScript==
var head = document.head || document.documentElement;

var script = document.createElement('script');
script.src = 'http://www.google.com/jsapi?key=ABQIAAAAfoo';
head.appendChild(script);

var script2 = document.createElement('script');
script2.textContent = '... code here ..';
head.appendChild(script2);

// Clean-up:
script.parentNode.removeChild(script);
script2.parentNode.removeChild(script2);

E4X instead of a plain string

The easiest option to embed a string of JavaScript code in your GreaseMonkey script, without escaping quotes and newlines is to use the E4X format:

script2.textContent = <x><![CDATA[ 
alert("test");
]]></x>.toString();
Rob W
  • 341,306
  • 83
  • 791
  • 678
1

I flagged this question as duplicate of how to use the google maps api with greasemonkey to read a table of addresses and trace the route? but the mod "found no evidence to support it".

So i will just copy-paste what i did in my question, since its not a duplicate...
Nah, just kidding :)

Lets start with your last statement:

I've found that if I don't include // @require http://www.google.com/jsapi?key=ABQIAAAAfoo in the Greasemonkey script, I get a google is undefined error. If I do include it, init_map() never gets called. Any suggestions?

Yes.
First, the google maps API should not be loaded as a @require. Instead, do it like this

API_js_callback = "http://maps.google.com/maps/api/js?sensor=false&region=BR&callback=initialize";

var script = document.createElement('script');
    script.src = API_js_callback;
var head = document.getElementsByTagName("head")[0];
    (head || document.body).appendChild(script);

Second, add google = unsafeWindow.google, otherwise you get the "google is undefined" error.
So, your code should start like this

var init_map = function() {
    google = unsafeWindow.google
    new google.maps.Geocoder().geocode . . . . . .

About the rest of your code... well, just click on the link above and there you will find how to create a DIV on the fly, add the map to it, append the DIV to the page in a fixed position, etc.

Feel free to copy whatever you want.

Greasemonkey scripts are free anyway :)

Community
  • 1
  • 1
RASG
  • 5,988
  • 4
  • 26
  • 47
1

I tested the answers here and in many other places and nothing would work. Maybe because the API is now v3 or who knows.

I am going to post the answer that worked for me, which is quite different from the others I found, and I believe can be used for many other cases. It's arguably a bit ugly, but after all this is script injection and nobody likes injections.

I don't copy the whole thing in jsbin / codepen / etc. because they simply cannot replicate the GS (Greasemonkey) environment (at least yet) and inner workings.

LOADING API

I had control over the destination webpage so this was there instead of being added via GS.

<script  src="https://maps.googleapis.com/maps/api/js?key=my-personal-key"></script>

On my experience, if you don't add the key, after a few requests it will fail and you will have to wait some time until it works again.

I also have there a div whith a floating window where I would create my map.

<div style="overflow:hidden; height:500px; width:700px; position:fixed; top:20px; right:20px; border:3px solid #73AD21;">
  <div id="gmap_canvas" style="height:500px;width:700px;"></div>
  <style>#gmap_canvas img{max-width:none!important;background:none!important}</style>
  <div id="Content_Title"></div>
</div>

GS SCRIPT

// Pass whatever data you need to the window
unsafeWindow.mapdata=JSON.stringify(mapdata);



// Define content of script   
var script2 = document.createElement('script');

script2.textContent = `        
      // Get data
      mapdata=JSON.parse(window.mapdata);

      // Create map and use data
      function initializeX2() {  

          // some stuff ...        

          // Create map
          var mapCanvas = document.getElementById('gmap_canvas');
          var myLatLng = {lat: parseFloat(mapdata[max].latitude), lng: parseFloat(mapdata[max].longitude)};
          var mapOptions = {
            center: myLatLng,
            zoom: 15,
            mapTypeControl: false,
            mapTypeId: google.maps.MapTypeId.ROADMAP
          };
          var map = new google.maps.Map(mapCanvas, mapOptions);

          var marker=[];
          var contentInfoWindow=[];
          var infowindow=[];

          // Create markers
          for (var i = max ; i > max-iterations  ; i--) {  
            // Create marker
            var BLatLng={lat: parseFloat(mapdata[i].latitude), lng: parseFloat(mapdata[i].longitude)};
            console.log(BLatLng);
            marker[i] = new google.maps.Marker({
              position: BLatLng,
              map: map
            });

            // Create infowindow
            contentInfoWindow[i]=mapdata[i].number + " - " + mapdata[i].name;
            infowindow[i] = new google.maps.InfoWindow({content: contentInfoWindow[i] });

            // The function has this strange form to take values of references instead of references (pointers)
            google.maps.event.addListener(marker[i], 'click', function(innerKey) {
            return function() {
                infowindow[innerKey].open(map, marker[innerKey]);
            }
          }(i));

            // Open markers
            infowindow[i].open(map, marker[i]);

          }; // end of for

      }; // end of initializeX2           

      initializeX2();    
`;    // End of string to be added to page

// Add script to the page   
var head = document.head || document.documentElement;
head.appendChild(script2);

// Clean-up:
script2.parentNode.removeChild(script2);      

Some explanations

In my case the markers are opened when created, and multiple may stay open. That is my desired behaviour. If you want something else you have to search around.

This may help you. Create only ONE window to have only one infowindow open at a time ( http://www.aspsnippets.com/Articles/Google-Maps-API-V3-Open-Show-only-one-InfoWindow-at-a-time-and-close-other-InfoWindow.aspx )

If someone has got the other solutions working with API v3 (via google = unsafeWindow.google ) I would be very interested to know.

Rub
  • 2,071
  • 21
  • 37