blob: 137308192649ce139e2c4bfb41f7dccb4ef1c380 [file] [log] [blame]
Hans Muller05250712015-01-15 11:19:21 -08001#!mojo mojo:js_content_handler
2
3define("main", [
4 "console",
Hans Muller05250712015-01-15 11:19:21 -08005 "mojo/public/js/core",
6 "mojo/public/js/unicode",
Alhaad Gokhale4b5bda42015-03-06 13:58:49 -08007 "mojo/services/location/public/interfaces/geocoder.mojom",
8 "mojo/services/location/public/interfaces/location.mojom",
Hans Muller05250712015-01-15 11:19:21 -08009 "mojo/services/public/js/application",
10 "mojo/services/network/public/interfaces/network_service.mojom",
11 "mojo/services/network/public/interfaces/url_loader.mojom",
12 "third_party/js/url",
Alhaad Gokhale4b5bda42015-03-06 13:58:49 -080013], function(console, core, unicode, geocoder, location, application, network,
14 loader, url) {
Hans Muller05250712015-01-15 11:19:21 -080015
16 const Application = application.Application;
17 const Bounds = geocoder.Bounds;
18 const Geocoder = geocoder.Geocoder;
19 const Geometry = geocoder.Geometry;
Alhaad Gokhale4b5bda42015-03-06 13:58:49 -080020 const Location = location.Location;
Hans Muller05250712015-01-15 11:19:21 -080021 const NetworkService = network.NetworkService;
22 const Result = geocoder.Result;
23 const Status = geocoder.Status;
24 const URLRequest = loader.URLRequest;
25 const URL = url.URL;
26
27 var netService;
28
29 Location.prototype.queryString = function() {
30 // TBD: format floats to 6 decimal places
31 return this.latitude + ", " + this.longitude;
32 }
33
34 Location.fromJSON = function(json) {
35 return !json ? null : new Location({
36 latitude: json.lat,
37 longitude: json.lng,
38 });
39 }
40
41 Bounds.fromJSON = function(json) {
42 return !json ? null : new Bounds({
43 northeast: Location.fromJSON(json.northeast),
44 southwest: Location.fromJSON(json.southwest),
45 });
46 }
47
48 Geometry.fromJSON = function(json) {
49 return !json ? null : new Geometry({
50 location: Location.fromJSON(json.location),
51 location_type: json.location_type,
52 viewport: Bounds.fromJSON(json.viewport),
53 bounds: Bounds.fromJSON(json.bounds),
54 });
55 }
56
57 Result.fromJSON = function(json) {
58 return !json ? null : new Result({
59 partial_match: !!json.partial_match,
60 formatted_address: json.formatted_address,
61 geometry: Geometry.fromJSON(json.geometry),
62 types: json.types,
63 // TBD: address_components
64 });
65 }
66
67 function parseGeocodeResponse(arrayBuffer) {
68 return JSON.parse(unicode.decodeUtf8String(new Uint8Array(arrayBuffer)));
69 }
70
71 function geocodeRequest(url) {
72 return new Promise(function(resolveRequest) {
73 var urlLoader;
74 netService.createURLLoader(function(urlLoaderProxy) {
75 urlLoader = urlLoaderProxy;
76 });
77
78 var urlRequest = new URLRequest({
79 url: url.format(),
80 method: "GET",
81 auto_follow_redirects: true
82 });
83
84 urlLoader.start(urlRequest).then(function(urlLoaderResult) {
85 core.drainData(urlLoaderResult.response.body).then(
86 function(drainDataResult) {
87 // TBD: handle drainData failure
88 var value = parseGeocodeResponse(drainDataResult.buffer);
89 resolveRequest({
90 status: value.status,
91 results: value.results.map(Result.fromJSON),
92 });
93 });
94 });
95 });
96 }
97
98 function geocodeURL(key, value, options) {
99 var url = new URL("https://maps.googleapis.com/maps/api/geocode/json");
100 url.query = {};
101 url.query[key] = value;
102 // TBD: add options url.query
103 return url;
104 }
105
106 class GeocoderImpl {
107 addressToLocation(address, options) {
108 return geocodeRequest(geocodeURL("address", address, options));
109 }
110
111 locationToAddress(location, options) {
112 return geocodeRequest(
113 geocodeURL("latlng", location.queryString(), options));
114 }
115 }
116
117 class GeocoderService extends Application {
118 initialize() {
119 netService = this.shell.connectToService(
120 "mojo:network_service", NetworkService);
121 }
122
123 acceptConnection(initiatorURL, serviceProvider) {
124 serviceProvider.provideService(Geocoder, GeocoderImpl);
125 }
126 }
127
128 return GeocoderService;
129});
130