Reputation: 1672
Say I'd like to find addresses on any webpage and have a click on each one of them insert a small Google Maps below the address.
The problem I'm running into is that the GMaps library must be loaded via a < script> tag. But because anything loaded via < script> is out of the Chrome extension execution context, the "google.maps" object won't be available to my content scripts.
Any thoughts on a workaround?
Upvotes: 2
Views: 5149
Reputation: 40179
What you could do is create an iframe that contains a page to your map viewer. Then you will belong in the context of Content Scripts and you have full access to Chrome's Message Passing.
Since I have created hundreds of extensions, I have done exactly this in tons of them, and some of them are available in my github.com/mohamedmansour page. I will show an example that I just did for this problem below, unfortunately it may contain bugs. Check my github page above for a more complete example.
map_viewer.html
page in your extension.<head>
tag the <script src="http://maps.google.com/maps?file=api.....
map_viewer.html
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/map_viewer.css" />
<script type="text/javascript" src="/js/map_viewer.js"></script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>
map_viewer.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'RenderMap') {
renderMap(request.data.latitude, request.data.longitude);
}
});
function renderMap(latitude, latitude) {
var map = new GMap2(document.getElementById('map_canvas'));
map.setCenter(new GLatLng(latitude, latitude), 13);
var marker = new GMarker(new GPoint(lng, lat));
map.addOverlay(marker);
}
webpage_content_script.js
...
// Unique ID to differentiate this content script from the rest of the web.
// or use the extension id from @@__extension_id__, I recall there was a bug, haven't
// checked if it got resolved though.
var UNIQUE_MAP_VIEWER_ID = 'crx_myextension_iframe';
var latitude = -1;
var longitude = -1;
/**
* Here is where you want to render a latitude and longitude. We create an iframe so we
* we can inject it. We just want to maintain a single instance of it though.
*/
function onRenderMap() {
var mapViewerDOM = document.getElementById(UNIQUE_MAP_VIEWER_ID);
if (mapViewerDOM) {
mapViewerDOM.parentNode.removeChild(mapViewerDOM);
}
mapViewerDOM = document.createElement('iframe');
mapViewerDOM.setAttribute('id', UNIQUE_MAP_VIEWER_ID);
mapViewerDOM.setAttribute('src', chrome.extension.getURL('map_viewer.html');
mapViewerDOM.setAttribute('frameBorder', '0');
mapViewerDOM.setAttribute('width', '99.90%');
mapViewerDOM.setAttribute('height', '100%');
mapViewerDOM.setAttribute('style', 'position: fixed; top: 0; left: 0; overflow: hidden; z-index: 99999');
mapViewerDOM.onload = function(e) {
sendResponse({
method: 'RenderMap',
data: {
latitude: latitude,
longitude: longitude
}
});
}
document.body.appendChild(mapViewerDOM);
}
...
I hope this would steer you in the right direction.
Thanks, Mohamed Mansour
Upvotes: 7